Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add eslint and prettier with git hooks integration #109

Merged
merged 4 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
env: {
es6: true,
node: true,
mocha: true,
},
extends: ['eslint:recommended', 'prettier'],
parserOptions: {
ecmaVersion: 8,
sourceType: 'module',
},
parser: 'babel-eslint',
rules: {
'linebreak-style': ['warn', 'unix'],
},
};
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tabWidth": 2,
"singleQuote": true
}
20 changes: 10 additions & 10 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo

Examples of behavior that contributes to creating a positive environment include:

* 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

## Our Responsibilities

Expand Down
150 changes: 84 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
![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)
[![Build Status](https://travis-ci.com/aravindnc/mongoose-paginate-v2.svg?branch=master)](https://travis-ci.com/aravindnc/mongoose-paginate-v2)
[![Dependency Status](https://david-dm.org/aravindnc/mongoose-paginate-v2.svg)](https://david-dm.org/aravindnc/mongoose-paginate-v2)
Expand All @@ -16,6 +17,7 @@ If you are looking for aggregate query pagination, use this one [mongoose-aggreg
[![NPM](https://nodei.co/npm/mongoose-paginate-v2.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/mongoose-paginate-v2)

## 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 cusror 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 below documentation is not perfect. Feel free to contribute. :)
Expand All @@ -31,7 +33,7 @@ npm install mongoose-paginate-v2
Add plugin to a schema and then use model `paginate` method:

```js
const mongoose = require('mongoose');
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');

const mySchema = new mongoose.Schema({
Expand All @@ -40,9 +42,9 @@ const mySchema = new mongoose.Schema({

mySchema.plugin(mongoosePaginate);

const myModel = mongoose.model('SampleModel', mySchema);
const myModel = mongoose.model('SampleModel', mySchema);

myModel.paginate().then({}) // Usage
myModel.paginate().then({}); // Usage
```

### Model.paginate([query], [options], [callback])
Expand All @@ -51,44 +53,44 @@ Returns promise

**Parameters**

* `[query]` {Object} - Query criteria. [Documentation](https://docs.mongodb.org/manual/tutorial/query-documents)
* `[options]` {Object}
- `[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)
- `[populate]` {Array | Object | String} - Paths which should be populated with other documents. [Documentation](http://mongoosejs.com/docs/api.html#query_Query-populate)
- `[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)
- `[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
- `[offset=0]` {Number} - Use `offset` or `page` to set skip position
- `[page=1]` {Number}
- `[limit=10]` {Number}
- `[customLabels]` {Object} - Developers can provide custom labels for manipulating the response data.
- `[pagination]` {Boolean} - If `pagination` is set to false, it will return all docs without adding limit condition. (Default: True)
- `[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)
- `[forceCountFn]` {Boolean} - Set this to true, if you need to support $geo queries. (Default: False)
- `[forceCountFn]` {Boolean} - Set this to true, if you need to support \$geo queries. (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
- `[callback(err, result)]` - If specified, the callback is called once pagination results are retrieved or when an error has occurred

**Return value**

Promise fulfilled with object having properties:

* `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 sl. number of first document.
- `meta` {Object} - Object of pagination meta data (Default false).

Please note that the above properties can be renamed by setting customLabels attribute.

Expand All @@ -101,11 +103,11 @@ const options = {
page: 1,
limit: 10,
collation: {
locale: 'en'
}
locale: 'en',
},
};

Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.docs
// result.totalDocs = 100
// result.limit = 10
Expand All @@ -123,17 +125,17 @@ Model.paginate({}, options, function(err, result) {

Now developers can specify the return field names if they want. Below are the list of attributes whose name can be changed.

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

You should pass the names of the properties you wish to changes using `customLabels` object in options.
Set the property to false to remove it from the result.
Expand All @@ -149,16 +151,16 @@ const myCustomLabels = {
prevPage: 'prev',
totalPages: 'pageCount',
pagingCounter: 'slNo',
meta: 'paginator'
meta: 'paginator',
};

const options = {
page: 1,
limit: 10,
customLabels: myCustomLabels
customLabels: myCustomLabels,
};

Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.itemsList [here docs become itemsList]
// result.paginator.itemCount = 100 [here totalDocs becomes itemCount]
// result.paginator.perPage = 10 [here limit becomes perPage]
Expand All @@ -177,7 +179,7 @@ Model.paginate({}, options, function(err, result) {
Using `offset` and `limit`:

```javascript
Model.paginate({}, { offset: 30, limit: 10 }, function(err, result) {
Model.paginate({}, { offset: 30, limit: 10 }, function (err, result) {
// result.docs
// result.totalPages
// result.limit - 10
Expand All @@ -188,25 +190,25 @@ Model.paginate({}, { offset: 30, limit: 10 }, function(err, result) {
With promise:

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

#### More advanced example

```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) {
// ...
});
```
Expand All @@ -216,7 +218,7 @@ Book.paginate(query, options).then(function(result) {
You can use `limit=0` to get only metadata:

```javascript
Model.paginate({}, { limit: 0 }).then(function(result) {
Model.paginate({}, { limit: 0 }).then(function (result) {
// result.docs - empty array
// result.totalDocs
// result.limit - 0
Expand All @@ -231,29 +233,30 @@ config.js:
var mongoosePaginate = require('mongoose-paginate-v2');

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

controller.js:

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

#### 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,

```javascript
const options = {
pagination: false
pagination: false,
};

Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.docs
// result.totalDocs = 100
// result.limit = 100
Expand All @@ -268,6 +271,7 @@ Model.paginate({}, options, function(err, result) {
```

#### Setting read preference.

Determines the MongoDB nodes from which to read.

```js
Expand All @@ -277,28 +281,32 @@ const options = {
page: 1,
read: {
pref: 'secondary',
tags: [{
region: 'South'
}]
}
tags: [
{
region: 'South',
},
],
},
};
Model.paginate({}, options, function(err, result) {
// Result

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
- $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.

Expand All @@ -307,19 +315,29 @@ const options = {
lean: true,
limit: 10,
page: 1,
forceCountFn: true
forceCountFn: true,
};
Model.paginate({}, options, function(err, result) {
// Result

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

[v1.3.10] - 1/11/2020

- Added support for estimatedCountDocuments for larger datasets. Set useEstimatedCount=true

[v1.3.11] - 6/11/2020

- Fixes to estimateDocumentCount implementation.
- Package version updates to support Node v12.

Expand Down
Loading