forked from Shereminskiy/loopback-soft-delete-mixin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
soft-delete.js
171 lines (122 loc) · 17.6 KB
/
soft-delete.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _extends6 = require('babel-runtime/helpers/extends');
var _extends7 = _interopRequireDefault(_extends6);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _debug2 = require('./debug');
var _debug3 = _interopRequireDefault(_debug2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var debug = (0, _debug3.default)();
exports.default = function (Model, _ref) {
var _ref$deletedAt = _ref.deletedAt,
deletedAt = _ref$deletedAt === undefined ? 'deletedAt' : _ref$deletedAt,
_ref$_isDeleted = _ref._isDeleted,
_isDeleted = _ref$_isDeleted === undefined ? '_isDeleted' : _ref$_isDeleted,
_ref$scrub = _ref.scrub,
scrub = _ref$scrub === undefined ? false : _ref$scrub;
debug('SoftDelete mixin for Model %s', Model.modelName);
debug('options', { deletedAt: deletedAt, _isDeleted: _isDeleted, scrub: scrub });
var properties = Model.definition.properties;
var scrubbed = {};
if (scrub !== false) {
var propertiesToScrub = scrub;
if (!Array.isArray(propertiesToScrub)) {
propertiesToScrub = (0, _keys2.default)(properties).filter(function (prop) {
return !properties[prop].id && prop !== _isDeleted;
});
}
scrubbed = propertiesToScrub.reduce(function (obj, prop) {
return (0, _extends7.default)({}, obj, (0, _defineProperty3.default)({}, prop, null));
}, {});
}
Model.defineProperty(deletedAt, { type: Date, required: false });
Model.defineProperty(_isDeleted, { type: Boolean, required: false, default: false });
Model.destroyAll = function softDestroyAll(where, cb) {
var _extends3;
return Model.updateAll(where, (0, _extends7.default)({}, scrubbed, (_extends3 = {}, (0, _defineProperty3.default)(_extends3, deletedAt, new Date()), (0, _defineProperty3.default)(_extends3, _isDeleted, true), _extends3))).then(function (result) {
return typeof cb === 'function' ? cb(null, result) : result;
}).catch(function (error) {
return typeof cb === 'function' ? cb(error) : _promise2.default.reject(error);
});
};
Model.remove = Model.destroyAll;
Model.deleteAll = Model.destroyAll;
Model.destroyById = function softDestroyById(id, cb) {
var _extends4;
return Model.updateAll({ id: id }, (0, _extends7.default)({}, scrubbed, (_extends4 = {}, (0, _defineProperty3.default)(_extends4, deletedAt, new Date()), (0, _defineProperty3.default)(_extends4, _isDeleted, true), _extends4))).then(function (result) {
return typeof cb === 'function' ? cb(null, result) : result;
}).catch(function (error) {
return typeof cb === 'function' ? cb(error) : _promise2.default.reject(error);
});
};
Model.removeById = Model.destroyById;
Model.deleteById = Model.destroyById;
Model.prototype.destroy = function softDestroy(options, cb) {
var _extends5;
var callback = cb === undefined && typeof options === 'function' ? options : cb;
return this.updateAttributes((0, _extends7.default)({}, scrubbed, (_extends5 = {}, (0, _defineProperty3.default)(_extends5, deletedAt, new Date()), (0, _defineProperty3.default)(_extends5, _isDeleted, true), _extends5))).then(function (result) {
return typeof cb === 'function' ? callback(null, result) : result;
}).catch(function (error) {
return typeof cb === 'function' ? callback(error) : _promise2.default.reject(error);
});
};
Model.prototype.remove = Model.prototype.destroy;
Model.prototype.delete = Model.prototype.destroy;
// Emulate default scope but with more flexibility.
var queryNonDeleted = {
or: [(0, _defineProperty3.default)({}, _isDeleted, null), (0, _defineProperty3.default)({}, _isDeleted, false)]
};
var _findOrCreate = Model.findOrCreate;
Model.findOrCreate = function findOrCreateDeleted() {
var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!query.where) query.where = {};
if (!query.deleted) {
query.where = { and: [query.where, queryNonDeleted] };
}
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
rest[_key - 1] = arguments[_key];
}
return _findOrCreate.call.apply(_findOrCreate, [Model, query].concat(rest));
};
var _find = Model.find;
Model.find = function findDeleted() {
var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!query.where) query.where = {};
if (!query.deleted) {
query.where = { and: [query.where, queryNonDeleted] };
}
for (var _len2 = arguments.length, rest = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
rest[_key2 - 1] = arguments[_key2];
}
return _find.call.apply(_find, [Model, query].concat(rest));
};
var _count = Model.count;
Model.count = function countDeleted() {
var where = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// Because count only receives a 'where', there's nowhere to ask for the deleted entities.
var whereNotDeleted = { and: [where, queryNonDeleted] };
for (var _len3 = arguments.length, rest = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
rest[_key3 - 1] = arguments[_key3];
}
return _count.call.apply(_count, [Model, whereNotDeleted].concat(rest));
};
var _update = Model.update;
Model.update = Model.updateAll = function updateDeleted() {
var where = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// Because update/updateAll only receives a 'where', there's nowhere to ask for the deleted entities.
var whereNotDeleted = { and: [where, queryNonDeleted] };
for (var _len4 = arguments.length, rest = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
rest[_key4 - 1] = arguments[_key4];
}
return _update.call.apply(_update, [Model, whereNotDeleted].concat(rest));
};
};
module.exports = exports['default'];
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvZnQtZGVsZXRlLmpzIl0sIm5hbWVzIjpbImRlYnVnIiwiTW9kZWwiLCJkZWxldGVkQXQiLCJfaXNEZWxldGVkIiwic2NydWIiLCJtb2RlbE5hbWUiLCJwcm9wZXJ0aWVzIiwiZGVmaW5pdGlvbiIsInNjcnViYmVkIiwicHJvcGVydGllc1RvU2NydWIiLCJBcnJheSIsImlzQXJyYXkiLCJmaWx0ZXIiLCJwcm9wIiwiaWQiLCJyZWR1Y2UiLCJvYmoiLCJkZWZpbmVQcm9wZXJ0eSIsInR5cGUiLCJEYXRlIiwicmVxdWlyZWQiLCJCb29sZWFuIiwiZGVmYXVsdCIsImRlc3Ryb3lBbGwiLCJzb2Z0RGVzdHJveUFsbCIsIndoZXJlIiwiY2IiLCJ1cGRhdGVBbGwiLCJ0aGVuIiwicmVzdWx0IiwiY2F0Y2giLCJlcnJvciIsInJlamVjdCIsInJlbW92ZSIsImRlbGV0ZUFsbCIsImRlc3Ryb3lCeUlkIiwic29mdERlc3Ryb3lCeUlkIiwicmVtb3ZlQnlJZCIsImRlbGV0ZUJ5SWQiLCJwcm90b3R5cGUiLCJkZXN0cm95Iiwic29mdERlc3Ryb3kiLCJvcHRpb25zIiwiY2FsbGJhY2siLCJ1bmRlZmluZWQiLCJ1cGRhdGVBdHRyaWJ1dGVzIiwiZGVsZXRlIiwicXVlcnlOb25EZWxldGVkIiwib3IiLCJfZmluZE9yQ3JlYXRlIiwiZmluZE9yQ3JlYXRlIiwiZmluZE9yQ3JlYXRlRGVsZXRlZCIsInF1ZXJ5IiwiZGVsZXRlZCIsImFuZCIsInJlc3QiLCJjYWxsIiwiX2ZpbmQiLCJmaW5kIiwiZmluZERlbGV0ZWQiLCJfY291bnQiLCJjb3VudCIsImNvdW50RGVsZXRlZCIsIndoZXJlTm90RGVsZXRlZCIsIl91cGRhdGUiLCJ1cGRhdGUiLCJ1cGRhdGVEZWxldGVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7Ozs7OztBQUNBLElBQU1BLFFBQVEsc0JBQWQ7O2tCQUVlLFVBQUNDLEtBQUQsUUFBa0Y7QUFBQSw0QkFBeEVDLFNBQXdFO0FBQUEs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VUFBTTtBQUFBOztBQUd2RCxXQUFPSyxPQUFPSixJQUFQLGdCQUFZdkQsS0FBWixFQUFtQjhELGVBQW5CLFNBQXVDUixJQUF2QyxFQUFQO0FBQ0QsR0FKRDs7QUFNQSxNQUFNUyxVQUFVL0QsTUFBTWdFLE1BQXRCO0FBQ0FoRSxRQUFNZ0UsTUFBTixHQUFlaEUsTUFBTTBCLFNBQU4sR0FBa0IsU0FBU3VDLGFBQVQsR0FBNEM7QUFBQSxRQUFyQnpDLEtBQXFCLHVFQUFiLEVBQWE7O0FBQzNFO0FBQ0EsUUFBTXNDLGtCQUFrQixFQUFFVCxLQUFLLENBQUU3QixLQUFGLEVBQVNzQixlQUFULENBQVAsRUFBeEI7O0FBRjJFLHVDQUFOUSxJQUFNO0FBQU5BLFVBQU07QUFBQTs7QUFHM0UsV0FBT1MsUUFBUVIsSUFBUixpQkFBYXZELEtBQWIsRUFBb0I4RCxlQUFwQixTQUF3Q1IsSUFBeEMsRUFBUDtBQUNELEdBSkQ7QUFLRCxDIiwiZmlsZSI6InNvZnQtZGVsZXRlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF9kZWJ1ZyBmcm9tICcuL2RlYnVnJztcbmNvbnN0IGRlYnVnID0gX2RlYnVnKCk7XG5cbmV4cG9ydCBkZWZhdWx0IChNb2RlbCwgeyBkZWxldGVkQXQgPSAnZGVsZXRlZEF0JywgX2lzRGVsZXRlZCA9ICdfaXNEZWxldGVkJywgc2NydWIgPSBmYWxzZSB9KSA9PiB7XG4gIGRlYnVnKCdTb2Z0RGVsZXRlIG1peGluIGZvciBNb2RlbCAlcycsIE1vZGVsLm1vZGVsTmFtZSk7XG5cbiAgZGVidWcoJ29wdGlvbnMnLCB7IGRlbGV0ZWRBdCwgX2lzRGVsZXRlZCwgc2NydWIgfSk7XG5cbiAgY29uc3QgcHJvcGVydGllcyA9IE1vZGVsLmRlZmluaXRpb24ucHJvcGVydGllcztcblxuICBsZXQgc2NydWJiZWQgPSB7fTtcbiAgaWYgKHNjcnViICE9PSBmYWxzZSkge1xuICAgIGxldCBwcm9wZXJ0aWVzVG9TY3J1YiA9IHNjcnViO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9wZXJ0aWVzVG9TY3J1YikpIHtcbiAgICAgIHByb3BlcnRpZXNUb1NjcnViID0gT2JqZWN0LmtleXMocHJvcGVydGllcylcbiAgICAgICAgLmZpbHRlcihwcm9wID0+ICFwcm9wZXJ0aWVzW3Byb3BdLmlkICYmIHByb3AgIT09IF9pc0RlbGV0ZWQpO1xuICAgIH1cbiAgICBzY3J1YmJlZCA9IHByb3BlcnRpZXNUb1NjcnViLnJlZHVjZSgob2JqLCBwcm9wKSA9PiAoeyAuLi5vYmosIFtwcm9wXTogbnVsbCB9KSwge30pO1xuICB9XG5cbiAgTW9kZWwuZGVmaW5lUHJvcGVydHkoZGVsZXRlZEF0LCB7dHlwZTogRGF0ZSwgcmVxdWlyZWQ6IGZhbHNlfSk7XG4gIE1vZGVsLmRlZmluZVByb3BlcnR5KF9pc0RlbGV0ZWQsIHt0eXBlOiBCb29sZWFuLCByZXF1aXJlZDogZmFsc2UsIGRlZmF1bHQ6IGZhbHNlfSk7XG5cbiAgTW9kZWwuZGVzdHJveUFsbCA9IGZ1bmN0aW9uIHNvZnREZXN0cm95QWxsKHdoZXJlLCBjYikge1xuICAgIHJldHVybiBNb2RlbC51cGRhdGVBbGwod2hlcmUsIHsgLi4uc2NydWJiZWQsIFtkZWxldGVkQXRdOiBuZXcgRGF0ZSgpLCBbX2lzRGVsZXRlZF06IHRydWUgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSA/IGNiKG51bGwsIHJlc3VsdCkgOiByZXN1bHQpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4gKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykgPyBjYihlcnJvcikgOiBQcm9taXNlLnJlamVjdChlcnJvcikpO1xuICB9O1xuXG4gIE1vZGVsLnJlbW92ZSA9IE1vZGVsLmRlc3Ryb3lBbGw7XG4gIE1vZGVsLmRlbGV0ZUFsbCA9IE1vZGVsLmRlc3Ryb3lBbGw7XG5cbiAgTW9kZWwuZGVzdHJveUJ5SWQgPSBmdW5jdGlvbiBzb2Z0RGVzdHJveUJ5SWQoaWQsIGNiKSB7XG4gICAgcmV0dXJuIE1vZGVsLnVwZGF0ZUFsbCh7IGlkOiBpZCB9LCB7IC4uLnNjcnViYmVkLCBbZGVsZXRlZEF0XTogbmV3IERhdGUoKSwgW19pc0RlbGV0ZWRdOiB0cnVlIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4gKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykgPyBjYihudWxsLCByZXN1bHQpIDogcmVzdWx0KVxuICAgICAgLmNhdGNoKGVycm9yID0+ICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpID8gY2IoZXJyb3IpIDogUHJvbWlzZS5yZWplY3QoZXJyb3IpKTtcbiAgfTtcblxuICBNb2RlbC5yZW1vdmVCeUlkID0gTW9kZWwuZGVzdHJveUJ5SWQ7XG4gIE1vZGVsLmRlbGV0ZUJ5SWQgPSBNb2RlbC5kZXN0cm95QnlJZDtcblxuICBNb2RlbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIHNvZnREZXN0cm95KG9wdGlvbnMsIGNiKSB7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoY2IgPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgPyBvcHRpb25zIDogY2I7XG5cbiAgICByZXR1cm4gdGhpcy51cGRhdGVBdHRyaWJ1dGVzKHsgLi4uc2NydWJiZWQsIFtkZWxldGVkQXRdOiBuZXcgRGF0ZSgpLCBbX2lzRGVsZXRlZF06IHRydWUgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSA/IGNhbGxiYWNrKG51bGwsIHJlc3VsdCkgOiByZXN1bHQpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4gKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykgPyBjYWxsYmFjayhlcnJvcikgOiBQcm9taXNlLnJlamVjdChlcnJvcikpO1xuICB9O1xuXG4gIE1vZGVsLnByb3RvdHlwZS5yZW1vdmUgPSBNb2RlbC5wcm90b3R5cGUuZGVzdHJveTtcbiAgTW9kZWwucHJvdG90eXBlLmRlbGV0ZSA9IE1vZGVsLnByb3RvdHlwZS5kZXN0cm95O1xuXG4gIC8vIEVtdWxhdGUgZGVmYXVsdCBzY29wZSBidXQgd2l0aCBtb3JlIGZsZXhpYmlsaXR5LlxuICBjb25zdCBxdWVyeU5vbkRlbGV0ZWQgPSB7XG4gICAgb3I6IFtcbiAgICAgIHsgW19pc0RlbGV0ZWRdOiBudWxsIH0sXG4gICAgICB7IFtfaXNEZWxldGVkXTogZmFsc2UgfSxcbiAgICBdLFxuICB9O1xuXG4gIGNvbnN0IF9maW5kT3JDcmVhdGUgPSBNb2RlbC5maW5kT3JDcmVhdGU7XG4gIE1vZGVsLmZpbmRPckNyZWF0ZSA9IGZ1bmN0aW9uIGZpbmRPckNyZWF0ZURlbGV0ZWQocXVlcnkgPSB7fSwgLi4ucmVzdCkge1xuICAgIGlmICghcXVlcnkud2hlcmUpIHF1ZXJ5LndoZXJlID0ge307XG5cbiAgICBpZiAoIXF1ZXJ5LmRlbGV0ZWQpIHtcbiAgICAgIHF1ZXJ5LndoZXJlID0geyBhbmQ6IFsgcXVlcnkud2hlcmUsIHF1ZXJ5Tm9uRGVsZXRlZCBdIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIF9maW5kT3JDcmVhdGUuY2FsbChNb2RlbCwgcXVlcnksIC4uLnJlc3QpO1xuICB9O1xuXG4gIGNvbnN0IF9maW5kID0gTW9kZWwuZmluZDtcbiAgTW9kZWwuZmluZCA9IGZ1bmN0aW9uIGZpbmREZWxldGVkKHF1ZXJ5ID0ge30sIC4uLnJlc3QpIHtcbiAgICBpZiAoIXF1ZXJ5LndoZXJlKSBxdWVyeS53aGVyZSA9IHt9O1xuXG4gICAgaWYgKCFxdWVyeS5kZWxldGVkKSB7XG4gICAgICBxdWVyeS53aGVyZSA9IHsgYW5kOiBbIHF1ZXJ5LndoZXJlLCBxdWVyeU5vbkRlbGV0ZWQgXSB9O1xuICAgIH1cblxuICAgIHJldHVybiBfZmluZC5jYWxsKE1vZGVsLCBxdWVyeSwgLi4ucmVzdCk7XG4gIH07XG5cbiAgY29uc3QgX2NvdW50ID0gTW9kZWwuY291bnQ7XG4gIE1vZGVsLmNvdW50ID0gZnVuY3Rpb24gY291bnREZWxldGVkKHdoZXJlID0ge30sIC4uLnJlc3QpIHtcbiAgICAvLyBCZWNhdXNlIGNvdW50IG9ubHkgcmVjZWl2ZXMgYSAnd2hlcmUnLCB0aGVyZSdzIG5vd2hlcmUgdG8gYXNrIGZvciB0aGUgZGVsZXRlZCBlbnRpdGllcy5cbiAgICBjb25zdCB3aGVyZU5vdERlbGV0ZWQgPSB7IGFuZDogWyB3aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICByZXR1cm4gX2NvdW50LmNhbGwoTW9kZWwsIHdoZXJlTm90RGVsZXRlZCwgLi4ucmVzdCk7XG4gIH07XG5cbiAgY29uc3QgX3VwZGF0ZSA9IE1vZGVsLnVwZGF0ZTtcbiAgTW9kZWwudXBkYXRlID0gTW9kZWwudXBkYXRlQWxsID0gZnVuY3Rpb24gdXBkYXRlRGVsZXRlZCh3aGVyZSA9IHt9LCAuLi5yZXN0KSB7XG4gICAgLy8gQmVjYXVzZSB1cGRhdGUvdXBkYXRlQWxsIG9ubHkgcmVjZWl2ZXMgYSAnd2hlcmUnLCB0aGVyZSdzIG5vd2hlcmUgdG8gYXNrIGZvciB0aGUgZGVsZXRlZCBlbnRpdGllcy5cbiAgICBjb25zdCB3aGVyZU5vdERlbGV0ZWQgPSB7IGFuZDogWyB3aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICByZXR1cm4gX3VwZGF0ZS5jYWxsKE1vZGVsLCB3aGVyZU5vdERlbGV0ZWQsIC4uLnJlc3QpO1xuICB9O1xufTtcbiJdfQ==