Skip to content

Commit e0b76cd

Browse files
committed
feat: ability to restore deleted models
1 parent fbf31b8 commit e0b76cd

File tree

9 files changed

+677
-330
lines changed

9 files changed

+677
-330
lines changed

dist/vuex-orm-soft-delete.common.js

Lines changed: 132 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -78,111 +78,131 @@ function __generator(thisArg, body) {
7878

7979
function Model(context, model) {
8080
/**
81-
* Flags are visible by default during model serialization.
82-
* They can be hidden by setting `exposeFlagsExternally` to false.
81+
* Soft delete model(s) matching a condition.
8382
*/
84-
var $fields = model.prototype.$fields;
85-
model.prototype.$fields = function () {
86-
var _a;
87-
var fields = $fields.call(this);
88-
var _b = context.createConfig(this.$self().softDeleteConfig), key = _b.key, flagName = _b.flagName;
89-
return Object.assign({}, fields, (_a = {},
90-
_a[key] = this.$self().attr(null),
91-
_a[flagName] = this.$self().attr(false),
92-
_a));
93-
};
94-
/**
95-
* Flags are visible by default during model serialization.
96-
* They can be hidden by setting `exposeFlagsExternally` to false.
97-
*/
98-
var $toJson = model.prototype.$toJson;
99-
model.prototype.$toJson = function () {
100-
var toJson = $toJson.call(this);
101-
var config = context.createConfig(this.$self().softDeleteConfig);
102-
if (config.exposeFlagsExternally !== true) {
103-
/* istanbul ignore next */
104-
var _a = toJson, _b = config.key, k = _a[_b], _c = config.flagName, fn = _a[_c], json = __rest(_a, [typeof _b === "symbol" ? _b : _b + "", typeof _c === "symbol" ? _c : _c + ""]);
105-
return json;
106-
}
107-
return toJson;
108-
};
109-
/**
110-
* ...
111-
*/
112-
var $fill = model.prototype.$fill;
113-
model.prototype.$fill = function (record) {
114-
var _a, _b;
115-
$fill.call(this, record);
116-
if (record) {
117-
var _c = context.createConfig(this.$self().softDeleteConfig), key = _c.key, flagName = _c.flagName;
118-
this[key] = (_a = record[key]) !== null && _a !== void 0 ? _a : null;
119-
this[flagName] = (_b = record[flagName]) !== null && _b !== void 0 ? _b : false;
120-
}
83+
model.softDelete = function (payload) {
84+
return this.dispatch('softDelete', payload);
12185
};
12286
/**
123-
* Soft delete the record on a model instance.
87+
* Soft delete a model instance.
12488
*/
125-
model.prototype.$softDelete = function () {
89+
model.prototype.$softDelete = function (hydrate) {
12690
return __awaiter(this, void 0, void 0, function () {
127-
var record, _a, key, flagName;
91+
var model, _a, key, flagName;
12892
return __generator(this, function (_b) {
12993
switch (_b.label) {
13094
case 0: return [4 /*yield*/, this.$dispatch('softDelete', this.$self().getIdFromRecord(this))];
13195
case 1:
132-
record = _b.sent();
96+
model = _b.sent();
97+
if (hydrate) {
98+
this.$fill(model.$getAttributes());
99+
return [2 /*return*/, this];
100+
}
133101
_a = context.createConfig(this.$self().softDeleteConfig), key = _a.key, flagName = _a.flagName;
134-
this[key] = record[key];
135-
this[flagName] = record[flagName];
136-
return [2 /*return*/, record];
102+
this[key] = model[key];
103+
this[flagName] = model[flagName];
104+
return [2 /*return*/, model];
137105
}
138106
});
139107
});
140108
};
141109
/**
142-
* Soft delete the record on a model instance.
143-
* This method is deprecated and will continue to warn dev environments of
144-
* this deprecation until completely removed.
110+
* Restore a model instance.
111+
*/
112+
model.prototype.$restore = function (hydrate) {
113+
return __awaiter(this, void 0, void 0, function () {
114+
var _a, key, flagName, model;
115+
var _b;
116+
return __generator(this, function (_c) {
117+
switch (_c.label) {
118+
case 0:
119+
_a = context.createConfig(this.$self().softDeleteConfig), key = _a.key, flagName = _a.flagName;
120+
return [4 /*yield*/, this.$dispatch('update', {
121+
where: this.$self().getIdFromRecord(this),
122+
data: (_b = {},
123+
_b[key] = null,
124+
_b[flagName] = false,
125+
_b)
126+
})];
127+
case 1:
128+
model = _c.sent();
129+
if (hydrate) {
130+
this.$fill(model.$getAttributes());
131+
return [2 /*return*/, this];
132+
}
133+
this[key] = model[key];
134+
this[flagName] = model[flagName];
135+
return [2 /*return*/, this];
136+
}
137+
});
138+
});
139+
};
140+
/**
141+
* Determine if the model instance has been soft deleted.
142+
*/
143+
model.prototype.$trashed = function () {
144+
var flagName = context.createConfig(this.$self().softDeleteConfig).flagName;
145+
return this[flagName] === true;
146+
};
147+
/**
148+
* Soft-delete a model instance.
149+
* This method is deprecated and will warn users until retired.
145150
* @deprecated since v1.2.0
146151
*/
147-
model.prototype.softDelete = function () {
152+
model.prototype.softDelete = function (hydrate) {
148153
/* istanbul ignore next */
149154
if (process.env.NODE_ENV !== 'production') {
150155
console.warn('The `softDelete` instance method has been deprecated. Please use `$softDelete`.');
151156
}
152-
return this.$softDelete();
157+
return this.$softDelete(hydrate);
153158
};
154159
/**
155-
* Determine if the instance has been soft deleted.
160+
* Add supporting attributes to model.
156161
*/
157-
model.prototype.trashed = function () {
158-
var flagName = context.createConfig(this.$self().softDeleteConfig).flagName;
159-
return this[flagName] === true;
162+
var $fields = model.prototype.$fields;
163+
model.prototype.$fields = function () {
164+
var _a;
165+
var fields = $fields.call(this);
166+
var _b = context.createConfig(this.$self().softDeleteConfig), key = _b.key, flagName = _b.flagName;
167+
return Object.assign({}, fields, (_a = {},
168+
_a[key] = this.$self().attr(null),
169+
_a[flagName] = this.$self().attr(false),
170+
_a));
160171
};
161172
/**
162-
* Soft delete record(s) matching a condition.
173+
* Flags are visible by default during model serialization. They can be hidden
174+
* by setting `exposeFlagsExternally` to false.
163175
*/
164-
model.softDelete = function (payload) {
165-
return this.dispatch('softDelete', payload);
176+
var $toJson = model.prototype.$toJson;
177+
model.prototype.$toJson = function () {
178+
var toJson = $toJson.call(this);
179+
var config = context.createConfig(this.$self().softDeleteConfig);
180+
if (config.exposeFlagsExternally !== true) {
181+
/* istanbul ignore next */
182+
var _a = toJson, _b = config.key, k = _a[_b], _c = config.flagName, fn = _a[_c], json = __rest(_a, [typeof _b === "symbol" ? _b : _b + "", typeof _c === "symbol" ? _c : _c + ""]);
183+
return json;
184+
}
185+
return toJson;
166186
};
167187
}
168188

169189
function Query(context, query) {
170190
/**
171-
* Determine if soft deletes should be filtered exclusively.
191+
* Determine if soft deleted models should be filtered exclusively.
172192
* true = only soft deletes
173193
* false = include soft deletes
174194
* null = exclude soft deletes
175195
*/
176196
query.prototype.softDeletesFilter = null;
177197
/**
178-
* Constraint includes soft deletes.
198+
* Constraint includes soft deleted models.
179199
*/
180200
query.prototype.withTrashed = function () {
181201
this.softDeletesFilter = false;
182202
return this;
183203
};
184204
/**
185-
* Constraint restricts to only soft deletes.
205+
* Constraint restricts to only soft deleted models.
186206
*/
187207
query.prototype.onlyTrashed = function () {
188208
this.softDeletesFilter = true;
@@ -199,21 +219,24 @@ function Query(context, query) {
199219
}
200220
return this.onlyTrashed();
201221
};
222+
/**
223+
* Process the model(s) to be soft deleted.
224+
*/
202225
query.prototype.softDelete = function (condition) {
203226
var _a;
204-
var config = context.createConfig(this.model.softDeleteConfig);
227+
var _b = context.createConfig(this.model.softDeleteConfig), key = _b.key, flagName = _b.flagName, mutator = _b.mutator;
205228
var value = Date.now();
206-
value = typeof config.mutator === 'function' ? config.mutator(value) : value;
229+
value = typeof mutator === 'function' ? mutator(value) : value;
207230
var data = (_a = {},
208-
_a[config.key] = value,
209-
_a[config.flagName] = true,
231+
_a[key] = value,
232+
_a[flagName] = true,
210233
_a);
211234
if (Array.isArray(condition)) {
212235
// Array of primary keys
213236
if (!this.model.isCompositePrimaryKey()) {
214237
return this.model.update({
215238
data: data,
216-
where: function (r) { return condition.includes(r[r.$primaryKey()]); }
239+
where: function (record) { return condition.includes(record[record.$primaryKey()]); }
217240
});
218241
}
219242
// Array of composite primary keys
@@ -227,19 +250,18 @@ function Query(context, query) {
227250
});
228251
}
229252
}
230-
return this.model.update({
231-
data: data,
232-
where: condition
233-
});
253+
return this.model.update({ data: data, where: condition });
234254
};
235255
/**
236-
* Fetch all soft deletes from the store
256+
* Fetch all soft deletes from the store.
237257
*/
238258
query.prototype.allTrashed = function () {
239-
return this.onlyTrashed().get();
259+
return this.newQuery()
260+
.onlyTrashed()
261+
.get();
240262
};
241263
/**
242-
* Fetch all soft deletes from the store and group them by entity.
264+
* Fetch all soft deletes from the store and group by entity.
243265
*/
244266
query.allTrashed = function (store) {
245267
var _this = this;
@@ -251,32 +273,32 @@ function Query(context, query) {
251273
}, {});
252274
};
253275
/**
254-
* Global select hook prevents soft deletes being selected unless queries are
255-
* explicity used with `withTrashed` or `onlyTrashed`.
276+
* Global select hook prevents soft deleted models from being selected unless
277+
* queries are explicity chained with `withTrashed` or `onlyTrashed`.
256278
*/
257279
query.on('beforeSelect', function (models) {
258280
var _this = this;
259281
return models.filter(function (model) {
260-
// Only soft deletes.
282+
// Only soft deletes
261283
if (_this.softDeletesFilter === true) {
262-
return model.trashed();
284+
return model.$trashed();
263285
}
264-
// Include soft deletes.
286+
// Include soft deletes
265287
if (_this.softDeletesFilter === false) {
266288
return models;
267289
}
268-
// Exclude soft deletes.
269-
return !model.trashed();
290+
// Exclude soft deletes
291+
return !model.$trashed();
270292
});
271293
});
272294
}
273295

274-
function Modules(context, modules) {
296+
function Actions(_context, actions) {
275297
var _this = this;
276298
/**
277-
* Soft delete records from the store.
299+
* Soft delete records and persist to the store.
278300
*/
279-
modules.actions.softDelete = function (context, payload) { return __awaiter(_this, void 0, void 0, function () {
301+
actions.softDelete = function (context, payload) { return __awaiter(_this, void 0, void 0, function () {
280302
var state, entity, where;
281303
var _a;
282304
return __generator(this, function (_b) {
@@ -286,10 +308,22 @@ function Modules(context, modules) {
286308
return [2 /*return*/, context.dispatch(state.$connection + "/softDelete", { entity: entity, where: where }, { root: true })];
287309
});
288310
}); };
311+
}
312+
313+
function Getters(_context, getters) {
314+
/**
315+
* Get all trashed records from the store and group by entity.
316+
*/
317+
getters.allTrashed = function (state, _getters, _rootState, rootGetters) { return function () {
318+
return rootGetters[state.$connection + "/allTrashed"](state.$name);
319+
}; };
320+
}
321+
322+
function RootActions(context, rootActions) {
289323
/**
290-
* Soft delete records from the store.
324+
* Soft delete records and persist the store.
291325
*/
292-
modules.rootActions.softDelete = function (_context, payload) {
326+
rootActions.softDelete = function (_context, payload) {
293327
return __awaiter(this, void 0, void 0, function () {
294328
var entity, where;
295329
return __generator(this, function (_a) {
@@ -298,16 +332,13 @@ function Modules(context, modules) {
298332
});
299333
});
300334
};
335+
}
336+
337+
function RootGetters(context, rootGetters) {
301338
/**
302-
* Get all soft deletes keyed by entity.
303-
*/
304-
modules.getters.allTrashed = function (state, _getters, _rootState, rootGetters) { return function () {
305-
return rootGetters[state.$connection + "/allTrashed"](state.$name);
306-
}; };
307-
/**
308-
* Get all soft deletes of given entity.
339+
* Get all trashed records belonging to an entity.
309340
*/
310-
modules.rootGetters.allTrashed = function (_state) {
341+
rootGetters.allTrashed = function (_state) {
311342
var _this = this;
312343
return function (entity) {
313344
if (entity) {
@@ -332,12 +363,10 @@ var VuexORMSoftDelete = /** @class */ (function () {
332363
function VuexORMSoftDelete(components, config) {
333364
this.model = components.Model;
334365
this.query = components.Query;
335-
this.modules = {
336-
actions: components.Actions,
337-
getters: components.Getters,
338-
rootGetters: components.RootGetters,
339-
rootActions: components.RootActions
340-
};
366+
this.actions = components.Actions;
367+
this.getters = components.Getters;
368+
this.rootActions = components.RootActions;
369+
this.rootGetters = components.RootGetters;
341370
this.config = this.createConfig(config);
342371
}
343372
/**
@@ -353,7 +382,10 @@ var VuexORMSoftDelete = /** @class */ (function () {
353382
VuexORMSoftDelete.prototype.plugin = function () {
354383
Model(this, this.model);
355384
Query(this, this.query);
356-
Modules(this, this.modules);
385+
Actions(this, this.actions);
386+
Getters(this, this.getters);
387+
RootActions(this, this.rootActions);
388+
RootGetters(this, this.rootGetters);
357389
};
358390
return VuexORMSoftDelete;
359391
}());

0 commit comments

Comments
 (0)