UNPKG

mongoose-smart-delete

Version:

A Mongoose plugin for implementing soft delete functionality, allowing documents to be marked as deleted without being removed from the database.

115 lines (91 loc) 3.46 kB
const Mongoose = require('mongoose') const Kareem = require('kareem') const Methods = {} class MongooseSmartDelete { constructor(context) { this.context = context this._op = null this._updateOp = null } modelDeleteOne(query = {}, options = {}) { options.softDelete = this._useSoftDelete(options) if (!options.softDelete) { return Methods.Model.deleteOne.call(this.context, query, options) } this._op = 'deleteOne' this._updateOp = 'updateOne' return this.query(query, {}, options) } documentDeleteOne(options = {}) { options.softDelete = this._useSoftDelete(options) if (!options.softDelete) { return Methods.Document.deleteOne.call(this.context, options) } this._op = 'deleteOne' this._updateOp = 'updateOne' return this.query({}, options) } documentRestoreOne(options = {}) { this._op = 'restoreOne' this._updateOp = 'updateOne' return this.query({}, options) } modelRestoreOne(query = {}, options = {}) { this._op = 'restoreOne' this._updateOp = 'updateOne' return this.query(query, options) } deleteMany(query = {}, options = {}) { options.softDelete = this._useSoftDelete(options) if (!options.softDelete) { return Methods.Model.deleteMany.call(this.context, query, options) } this._op = 'deleteMany' this._updateOp = 'updateMany' return this.query(query, {}, options) } findOneAndDelete(query = {}, options = {}) { options.softDelete = this._useSoftDelete(options) if (!options.softDelete) { return Methods.Model.findOneAndDelete.call(this.context, query, options) } this._op = 'findOneAndDelete' this._updateOp = 'findOneAndUpdate' return this.query(query, options) } restoreMany(query = {}, options = {}) { this._op = 'restoreMany' this._updateOp = 'updateMany' return this.query(query, options) } _useSoftDelete(options = {}) { return this.context.schema._smartDelete && options.softDelete !== false } query() { // Create a new query with the corresponding update operation const query = this.context[this._updateOp].apply(this.context, arguments) // Move query middleware for delete/restore operation to the corresponding update operation const queryMiddleware = new Kareem() if (query._queryMiddleware._pres?.has(this._op)) queryMiddleware._pres.set(this._updateOp, query._queryMiddleware._pres.get(this._op)) if (query._queryMiddleware._posts?.has(this._op)) queryMiddleware._posts.set(this._updateOp, query._queryMiddleware._posts.get(this._op)) query._queryMiddleware = queryMiddleware // Move document middleware for delete/restore operation to the corresponding update operation if (this.context instanceof Mongoose.Document) { query._hooks._pres.set('exec', []) query._hooks._posts.set('exec', []) const self = this.context const op = this._op query.pre(function queryPreSoftDeleteUpdateOne(cb) { self.constructor._middleware.execPre(op, self, [query.getOptions()], cb) }) query.post(function queryPostSoftDeleteUpdateOne(cb) { self.constructor._middleware.execPost(op, self, [query.getOptions()], {}, cb) }) } return query } static setOriginalMethods(methods) { Object.assign(Methods, methods) } } module.exports = MongooseSmartDelete