UNPKG

k-mongoose-soft-delete

Version:

An advanced package for softdeleting models with mongoose

123 lines (96 loc) 3.34 kB
"use strict"; let _ = require('lodash'), shortId = require('shortid'); module.exports = function(schema) { // Not apply hash in childSchemas if(schema.options.__isChildSchema !== true) { // Calculate if has ChildSchemas to no apply hash _.forEach(schema.childSchemas, function (childSchema) { childSchema.schema.options.__isChildSchema = true; }); schema.statics.SOFT_DELETE = 1; schema.add({deleted: {type: Boolean, 'default': false, select: false, index: true}}); schema.add({deletedAt: {type: Date, 'default': null, select: false}}); schema.pre('save', function (next) { var doc = this; if (!doc.deleted) { doc.deleted = false; doc.deletedAt = null; } next(); }); // All mongoose queries are built using these base queries, // therefore adding the `archived` and `removed` logic to these queries adds it to all queries. let queries = ['find', 'findOne', 'findOneAndUpdate', 'update', 'count']; // add pre-query logic queries.forEach(function (query) { schema.pre(query, function (next) { // Only query documents that do not have the removed flag set to true. // Setting {deleted: {$ne: null}} overrides this and only queries removed documents. // TODO how to show deleted? this.where({ deleted: { '$eq': false } }); next(); }); }); } let soft_delete_fields = []; schema.eachPath(function (pathname, schemaType) { if (schemaType.instance == "String" && schemaType.options && schemaType.options.soft_delete_action) { var field = { "name": pathname }; if (typeof(schemaType.options.soft_delete_action) === "string") { field.action = schemaType.options.soft_delete_action; } else { field.action = null; } soft_delete_fields.push(field); } }); schema.methods.softDelete = async function softDelete() { try { var doc = this; doc.deleted = true; doc.deletedAt = new Date(); _.forEach(soft_delete_fields, function (field) { switch (field.action) { case "null": case null: doc[field.name] = null; break; case "suffix": doc[field.name] += "-" + shortId(); break; case "prefix": doc[field.name] = shortId() + "-" + doc[field.name]; break; case "replace": doc[field.name] = shortId() + "-" + shortId() + "-" + shortId(); break; } }); await doc.save(); }catch (err) { return Promise.reject(err); } }; schema.methods.restore = function(callback) { this.deleted = null; this.save(callback); }; let removeFields = function (doc, ret, options) { if (!ret.deleted) { delete ret.deleted; delete ret.deletedAt; } return ret; }; schema.set('toJSON', { transform: removeFields }); schema.set('toObject', { transform: removeFields }); };