mongoose-bread
Version:
A pagination and softdelete library for mongoose
297 lines (240 loc) • 11.3 kB
Markdown
# bread snippets
## Setup
If your are using VSCode you'll find some handy shortcuts through the use of snippets.
So mongoose-bread provides them for your convience (and mine) too.
Just add the file "bread.code-snippets" in `.vscode/bread.code-snippets` to your own `.vscode` folder.
If you don't have one yet - it belongs in the root of your project.
## But why not make an extension out of it?
Every project has its own needs and setups, so providing a extension to write the shortcuts for everyone seems like an impossible task. The idea behind these snippets is to give you a quick setup so you can play with mongoose-bread faster. After that tailor the snippets to your needs. You can even put the `.vscode` folder in your repo and make setups for everyone on your team consistent.
## Usage
To use the snippets just type "bread" (maybe hit <kbd>CMD</kbd> | <kbd>CTRL</kbd> + <kbd>Space</kbd>) in any `javascript` or `typescript` file, then select the one you need.
These snippets are provided.
- global Options
- Router
- softDelete Router
- Model
- softDelete Model
- Controller
- softDelete Controller
For everyone who is not using VSCode, here is the output of all the snippets:
## global Options
```javascript
/* use in server|main|index.js */
// set global mongoose-bread options
const { mongooseBread } = require('mongoose-bread')
mongooseBread.options = {
defaultPageSize: 10, // limits queries to return 10 documents - default: 10
maxPageSize: 100, // limits queries to return 100 documents max - default: 100
paramsIdKey: 'id', // expected request.params.id to identify a single Resource - default: id
// i.e. https://test.org/books/6478d57784fabdbf127d0a2a
// => router.get(books/:id, BookController.read)
// => request.params.id = 6478d57784fabdbf127d0a2a
bulkIdsKey: '_ids', // expected request.body._ids - default: '_ids'
// Used for bulk edit|add|destroy|softDelete|rehabilitate
bulkDocsKey: '_docs', // expected request.body._docs with Array<any> - default: _docs
// Used for bulk|edit|add
// => request.body: { _docs: [{name: 'newDoc#1'}, {name: 'newDoc#2'}] }
allowDiskUse: false, // allow MongoDB queries to use more than 100 MB - default: false
customLabels: { // optional - set custom keys for results
docs: 'docs', // default: 'docs'
meta: 'pagination', // default: 'pagination'
limit: 'limit', // default: 'limit'
page: 'page', // default: 'page'
pagingCounter: 'pagingCounter', // default: 'pagingCounter'
hasNextPage: 'hasNextPage', // default: 'hasNextPage'
hasPrevPage: 'hasPrevPage', // default: 'hasPrevPage'
nextPage: 'nextPage', // default: 'nextPage'
prevPage: 'prevPage', // default: 'prevPage'
totalDocs: 'totalDocs', // default: 'totalDocs'
totalPages: 'totalPages', // default: 'totalPages'
acknowledged: 'acknowledged', // default: 'acknowledged'
modifiedCount: 'modifiedCount', // default: 'modifiedCount'
deletedCount: 'deletedCount', // default: 'deletedCount'
createdCount: 'createdCount', // default: 'createdCount'
readCount: 'readCount', // default: 'readCount'
},
}
```
## Router
```javascript
const express = require("express");
const ResourceController = require("../Controller/ResourceController");
const router = express.Router()
router.use(auth-middleware)
/* use "bread softDelete Router" snippet if pluginOptions.softDelete = true */
router.get( '/:id', middleware, ResourceController.read)
router.patch( '/:id', middleware, ResourceController.edit)
router.delete('/:id', middleware, ResourceController.destroy)
router.get( '/', middleware, ResourceController.browse)
router.patch( '/', middleware, ResourceController.edit)
router.delete('/', middleware, ResourceController.destroy)
router.post( '/', middleware, ResourceController.add)
module.exports = router
```
## softDelete Router
```javascript
const express = require("express");
const ResourceController = require("../Controller/ResourceController");
const router = express.Router()
router.use(auth-middleware)
/* use "bread Router" snippet if pluginOptions.softDelete = false */
router.get( '/bin/:id', middleware, ResourceController.readDeleted)
router.patch( '/bin/:id', middleware, ResourceController.rehabilitate)
router.delete('/bin/:id', middleware, ResourceController.destroy)
router.get( '/bin', middleware, ResourceController.browseDeleted)
router.patch( '/bin', middleware, ResourceController.rehabilitate)
router.delete('/bin', middleware, ResourceController.destroy)
router.get( '/:id', middleware, ResourceController.read)
router.patch( '/:id', middleware, ResourceController.edit)
router.delete('/:id', middleware, ResourceController.softDelete)
router.get( '/', middleware, ResourceController.browse)
router.patch( '/', middleware, ResourceController.edit)
router.delete('/', middleware, ResourceController.softDelete)
router.post( '/', middleware, ResourceController.add)
module.exports = router
```
## Model
```javascript
const mongoose = require("mongoose");
const bread = require("mongoose-bread");
const resourceSchema = new mongoose.Schema({
name: String,
}, {
timestamps: true,
});
resourceSchema.plugin(bread, {
/* lean gets query results as plain js objects - can improve query speed */
// lean: false, // default: false
// leanWithId: false, // default: false
// leanWithout_id: false, // default: false
/* if searchableFields is ommited search will be disabled for resource */
searchableFields: ['name'],
/* exclude blacklistedFields from all query results */
blacklistedFields: ['__v', 'createdAt', 'updatedAt'],
})
module.exports = mongoose.model('resource', resourceSchema);
```
## softDelete Model
```javascript
const mongoose = require("mongoose");
const bread = require("mongoose-bread");
const resourceSchema = new mongoose.Schema({
name: String,
}, {
timestamps: true,
});
resourceSchema.plugin(bread, {
/* lean gets query results as plain js objects - can improve query speed */
// lean: false, // default: false
// leanWithId: false, // default: false
// leanWithout_id: false, // default: false
/* if searchableFields is ommited search will be disabled for resource */
searchableFields: ['name'],
/* exclude blacklistedFields from all query results */
blacklistedFields: ['__v', 'deleted', 'deletedAt', 'deletedBy', 'createdAt', 'updatedAt'],
/* enables softDelete */
softDelete: true,
softDeleteOptions: {
deletedAt: true, // default: true
deletedBy: true, // default: false
requestUserIdPath: 'auth.user.id' // default: ''
}
})
module.exports = mongoose.model('resource', resourceSchema);
```
## Controller
```javascript
const Resource = require("../Models/Resource")
function catchAsync(fn) { return (req, res, next) => { fn(req, res, next).catch(next) } }
/* use "bread softDelete Controller" snippet if pluginOptions.softDelete = true */
module.exports = {
browse: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createBrowseOptions(req)
const result = await Resource.browse(options)
res.status(200).json({
message: req.query.search ? 'search' : 'browse',
result,
})
}),
read: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createReadOptions(req)
const result = await Resource.read(options)
res.status(200).json({ message: 'read', result })
}),
edit: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createEditOptions(req)
const result = await Resource.edit(options)
res.status(200).json({ message: 'edit', result })
}),
add: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createAddOptions(req)
const result = await Resource.add(options)
res.status(200).json({ message: 'add', result })
}),
destroy: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createDeleteOptions(req)
const result = await Resource.destroy(options)
res.status(200).json({ message: 'destroy', result })
}),
}
```
## softDelete Controller
```javascript
const Resource = require("../Models/Resource")
function catchAsync(fn) { return (req, res, next) => { fn(req, res, next).catch(next) } }
/* use "bread Controller" snippet if pluginOptions.softDelete = false */
module.exports = {
browse: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createBrowseOptions(req)
const result = await Resource.browse(options)
res.status(200).json({
message: req.query.search ? 'search' : 'browse',
result,
})
}),
read: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createReadOptions(req)
const result = await Resource.read(options)
res.status(200).json({ message: 'read', result })
}),
edit: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createEditOptions(req)
const result = await Resource.edit(options)
res.status(200).json({ message: 'edit', result })
}),
add: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createAddOptions(req)
const result = await Resource.add(options)
res.status(200).json({ message: 'add', result })
}),
destroy: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createDeleteOptions(req)
const result = await Resource.destroy(options)
res.status(200).json({ message: 'destroy', result })
}),
/* softDelete methods */
browseDeleted: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createBrowseDeletedOptions(req)
const result = await Resource.browse(options)
res.status(200).json({
message: req.query.search ? 'searchDeleted' : 'browseDeleted',
result,
})
}),
readDeleted: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createReadDeletedOptions(req)
const result = await Resource.read(options)
res.status(200).json({ message: 'readDeleted', result })
}),
softDelete: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createDeleteOptions(req)
const result = await Resource.softDelete(options)
res.status(200).json({ message: 'softDelete', result })
}),
rehabilitate: catchAsync(async (req, res) => {
const options = Resource.breadHelper().createRehabilitateOptions(req)
const result = await Resource.rehabilitate(options)
res.status(200).json({ message: 'rehabilitate', result })
}),
}
```