@webda/core 1.2.1 → 1.6.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/application.d.ts +3 -0
- package/lib/application.js +26 -22
- package/lib/application.js.map +1 -1
- package/lib/application.spec.js +185 -2
- package/lib/application.spec.js.map +1 -1
- package/lib/core.d.ts +62 -6
- package/lib/core.js +127 -86
- package/lib/core.js.map +1 -1
- package/lib/core.spec.js +151 -6
- package/lib/core.spec.js.map +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/models/aclmodel.d.ts +42 -3
- package/lib/models/aclmodel.js +58 -3
- package/lib/models/aclmodel.js.map +1 -1
- package/lib/models/aclmodel.spec.js +46 -0
- package/lib/models/aclmodel.spec.js.map +1 -1
- package/lib/models/coremodel.d.ts +58 -10
- package/lib/models/coremodel.js +39 -32
- package/lib/models/coremodel.js.map +1 -1
- package/lib/models/coremodel.spec.js +68 -6
- package/lib/models/coremodel.spec.js.map +1 -1
- package/lib/models/ident.d.ts +8 -2
- package/lib/models/ident.js.map +1 -1
- package/lib/models/ident.spec.js +16 -0
- package/lib/models/ident.spec.js.map +1 -1
- package/lib/models/ownermodel.d.ts +1 -1
- package/lib/models/ownermodel.js.map +1 -1
- package/lib/models/ownermodel.spec.js +22 -19
- package/lib/models/ownermodel.spec.js.map +1 -1
- package/lib/models/user.d.ts +2 -0
- package/lib/models/user.js +4 -2
- package/lib/models/user.js.map +1 -1
- package/lib/models/user.spec.js +9 -2
- package/lib/models/user.spec.js.map +1 -1
- package/lib/queues/filequeue.d.ts +63 -0
- package/lib/queues/filequeue.js +161 -0
- package/lib/queues/filequeue.js.map +1 -0
- package/lib/queues/filequeue.spec.d.ts +1 -0
- package/lib/queues/filequeue.spec.js +90 -0
- package/lib/queues/filequeue.spec.js.map +1 -0
- package/lib/queues/memoryqueue.d.ts +18 -4
- package/lib/queues/memoryqueue.js +20 -13
- package/lib/queues/memoryqueue.js.map +1 -1
- package/lib/queues/memoryqueue.spec.js +142 -39
- package/lib/queues/memoryqueue.spec.js.map +1 -1
- package/lib/queues/pubsubservice.d.ts +27 -0
- package/lib/queues/pubsubservice.js +21 -0
- package/lib/queues/pubsubservice.js.map +1 -0
- package/lib/queues/queue.spec.js +16 -7
- package/lib/queues/queue.spec.js.map +1 -1
- package/lib/queues/queueservice.d.ts +108 -13
- package/lib/queues/queueservice.js +100 -36
- package/lib/queues/queueservice.js.map +1 -1
- package/lib/router.js +4 -6
- package/lib/router.js.map +1 -1
- package/lib/router.spec.js +27 -2
- package/lib/router.spec.js.map +1 -1
- package/lib/services/asyncevents.d.ts +110 -5
- package/lib/services/asyncevents.js +134 -39
- package/lib/services/asyncevents.js.map +1 -1
- package/lib/services/asyncevents.spec.js +58 -4
- package/lib/services/asyncevents.spec.js.map +1 -1
- package/lib/services/authentication.d.ts +57 -5
- package/lib/services/authentication.js +93 -84
- package/lib/services/authentication.js.map +1 -1
- package/lib/services/authentication.spec.js +118 -82
- package/lib/services/authentication.spec.js.map +1 -1
- package/lib/services/binary.d.ts +175 -48
- package/lib/services/binary.js +205 -170
- package/lib/services/binary.js.map +1 -1
- package/lib/services/binary.spec.d.ts +22 -3
- package/lib/services/binary.spec.js +327 -22
- package/lib/services/binary.spec.js.map +1 -1
- package/lib/services/configuration.d.ts +94 -13
- package/lib/services/configuration.js +98 -28
- package/lib/services/configuration.js.map +1 -1
- package/lib/services/configuration.spec.js +40 -1
- package/lib/services/configuration.spec.js.map +1 -1
- package/lib/services/cron.d.ts +4 -4
- package/lib/services/cron.js +37 -53
- package/lib/services/cron.js.map +1 -1
- package/lib/services/cron.spec.d.ts +1 -0
- package/lib/services/cron.spec.js +76 -0
- package/lib/services/cron.spec.js.map +1 -0
- package/lib/services/debugmailer.spec.js +18 -4
- package/lib/services/debugmailer.spec.js.map +1 -1
- package/lib/services/echo.js +22 -13
- package/lib/services/echo.js.map +1 -1
- package/lib/services/echo.spec.d.ts +1 -0
- package/lib/services/echo.spec.js +52 -0
- package/lib/services/echo.spec.js.map +1 -0
- package/lib/services/filebinary.d.ts +16 -9
- package/lib/services/filebinary.js +58 -73
- package/lib/services/filebinary.js.map +1 -1
- package/lib/services/filebinary.spec.d.ts +8 -1
- package/lib/services/filebinary.spec.js +133 -7
- package/lib/services/filebinary.spec.js.map +1 -1
- package/lib/services/fileconfiguration.d.ts +9 -3
- package/lib/services/fileconfiguration.js +13 -6
- package/lib/services/fileconfiguration.js.map +1 -1
- package/lib/services/fileconfiguration.spec.js +100 -5
- package/lib/services/fileconfiguration.spec.js.map +1 -1
- package/lib/services/kubernetesconfiguration.d.ts +8 -2
- package/lib/services/kubernetesconfiguration.js +16 -5
- package/lib/services/kubernetesconfiguration.js.map +1 -1
- package/lib/services/kubernetesconfiguration.spec.js +53 -16
- package/lib/services/kubernetesconfiguration.spec.js.map +1 -1
- package/lib/services/mailer.d.ts +11 -2
- package/lib/services/mailer.js +28 -34
- package/lib/services/mailer.js.map +1 -1
- package/lib/services/mailer.spec.js +69 -23
- package/lib/services/mailer.spec.js.map +1 -1
- package/lib/services/oauth.d.ts +5 -2
- package/lib/services/oauth.js +22 -8
- package/lib/services/oauth.js.map +1 -1
- package/lib/services/oauth.spec.js +33 -3
- package/lib/services/oauth.spec.js.map +1 -1
- package/lib/services/resource.spec.js +39 -2
- package/lib/services/resource.spec.js.map +1 -1
- package/lib/services/service.d.ts +16 -0
- package/lib/services/service.js +47 -6
- package/lib/services/service.js.map +1 -1
- package/lib/services/service.spec.d.ts +1 -0
- package/lib/services/service.spec.js +119 -0
- package/lib/services/service.spec.js.map +1 -0
- package/lib/stores/aggregator.d.ts +43 -0
- package/lib/stores/aggregator.js +106 -0
- package/lib/stores/aggregator.js.map +1 -0
- package/lib/stores/file.d.ts +49 -11
- package/lib/stores/file.js +84 -81
- package/lib/stores/file.js.map +1 -1
- package/lib/stores/file.spec.d.ts +6 -1
- package/lib/stores/file.spec.js +134 -9
- package/lib/stores/file.spec.js.map +1 -1
- package/lib/stores/mapper.d.ts +151 -0
- package/lib/stores/mapper.js +294 -0
- package/lib/stores/mapper.js.map +1 -0
- package/lib/stores/mapper.spec.d.ts +1 -0
- package/lib/stores/mapper.spec.js +55 -0
- package/lib/stores/mapper.spec.js.map +1 -0
- package/lib/stores/memory.d.ts +52 -7
- package/lib/stores/memory.js +71 -33
- package/lib/stores/memory.js.map +1 -1
- package/lib/stores/memory.spec.d.ts +6 -1
- package/lib/stores/memory.spec.js +65 -4
- package/lib/stores/memory.spec.js.map +1 -1
- package/lib/stores/store.d.ts +263 -126
- package/lib/stores/store.js +285 -493
- package/lib/stores/store.js.map +1 -1
- package/lib/stores/store.spec.d.ts +20 -0
- package/lib/stores/store.spec.js +242 -18
- package/lib/stores/store.spec.js.map +1 -1
- package/lib/test.d.ts +1 -7
- package/lib/test.js +3 -12
- package/lib/test.js.map +1 -1
- package/lib/utils/abstractdeployer.spec.d.ts +1 -0
- package/lib/utils/abstractdeployer.spec.js +23 -0
- package/lib/utils/abstractdeployer.spec.js.map +1 -0
- package/lib/utils/context.d.ts +25 -2
- package/lib/utils/context.js +33 -12
- package/lib/utils/context.js.map +1 -1
- package/lib/utils/context.spec.js +81 -11
- package/lib/utils/context.spec.js.map +1 -1
- package/lib/utils/cookie.d.ts +12 -0
- package/lib/utils/cookie.js +13 -1
- package/lib/utils/cookie.js.map +1 -1
- package/lib/utils/cookie.spec.js +42 -11
- package/lib/utils/cookie.spec.js.map +1 -1
- package/lib/utils/logger.d.ts +23 -4
- package/lib/utils/logger.js +29 -6
- package/lib/utils/logger.js.map +1 -1
- package/lib/utils/logger.spec.js +8 -0
- package/lib/utils/logger.spec.js.map +1 -1
- package/lib/utils/serializers.d.ts +5 -5
- package/lib/utils/serializers.js +10 -10
- package/lib/utils/serializers.js.map +1 -1
- package/lib/utils/serializers.spec.js +41 -16
- package/lib/utils/serializers.spec.js.map +1 -1
- package/lib/utils/waiter.d.ts +59 -1
- package/lib/utils/waiter.js +86 -3
- package/lib/utils/waiter.js.map +1 -1
- package/lib/utils/waiter.spec.js +48 -4
- package/lib/utils/waiter.spec.js.map +1 -1
- package/package.json +16 -11
- package/test/badapp/package.json +4 -0
- package/test/badapp/webda.config.json +1 -0
- package/test/cachedapp/webda.config.json +7 -0
- package/test/config-file-no-reload.json +70 -0
- package/test/config-file-reload.json +7 -1
- package/test/config-kube-reload.json +7 -1
- package/test/config.json +45 -21
- package/test/config.old-default.json +0 -16
- package/test/config.old.json +0 -16
- package/test/deployments/invalid.json +1 -0
- package/test/moddas/fakeservice.js +5 -0
- package/test/models/ident.js +10 -14
- package/test/models/task.js +2 -4
package/lib/stores/store.js
CHANGED
|
@@ -9,19 +9,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.Store = exports.StoreParameters = void 0;
|
|
13
|
-
const
|
|
12
|
+
exports.Store = exports.StoreParameters = exports.UpdateConditionFailError = exports.StoreNotFoundError = void 0;
|
|
13
|
+
const core_1 = require("../core");
|
|
14
|
+
const coremodel_1 = require("../models/coremodel");
|
|
14
15
|
const service_1 = require("../services/service");
|
|
16
|
+
class StoreNotFoundError extends core_1.WebdaError {
|
|
17
|
+
constructor(uuid, storeName) {
|
|
18
|
+
super("STORE_NOTFOUND", `Item not found ${uuid} Store(${storeName})`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.StoreNotFoundError = StoreNotFoundError;
|
|
22
|
+
class UpdateConditionFailError extends core_1.WebdaError {
|
|
23
|
+
constructor(uuid, conditionField, condition) {
|
|
24
|
+
super("STORE_UPDATE_CONDITION_FAILED", `UpdateCondition not met on ${uuid}.${conditionField} === ${condition instanceof Date ? condition.toISOString() : condition}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.UpdateConditionFailError = UpdateConditionFailError;
|
|
15
28
|
/**
|
|
16
29
|
* Store parameter
|
|
17
30
|
*/
|
|
18
31
|
class StoreParameters extends service_1.ServiceParameters {
|
|
19
32
|
constructor(params, service) {
|
|
20
|
-
var _a, _b
|
|
33
|
+
var _a, _b;
|
|
21
34
|
super(params);
|
|
22
|
-
(_a = this.
|
|
23
|
-
(_b = this.creationDateField) !== null && _b !== void 0 ? _b : (this.creationDateField = "_creationDate");
|
|
24
|
-
(_c = this.model) !== null && _c !== void 0 ? _c : (this.model = "Webda/CoreModel");
|
|
35
|
+
(_a = this.model) !== null && _a !== void 0 ? _a : (this.model = "Webda/CoreModel");
|
|
25
36
|
let expose = params.expose;
|
|
26
37
|
if (typeof expose == "boolean") {
|
|
27
38
|
expose = {};
|
|
@@ -39,6 +50,13 @@ class StoreParameters extends service_1.ServiceParameters {
|
|
|
39
50
|
expose.restrict = expose.restrict || {};
|
|
40
51
|
this.expose = expose;
|
|
41
52
|
}
|
|
53
|
+
if (params.map) {
|
|
54
|
+
throw new Error("Deprecated map usage, use a MapperService");
|
|
55
|
+
}
|
|
56
|
+
if (params.index) {
|
|
57
|
+
throw new Error("Deprecated index usage, use an AggregatorService");
|
|
58
|
+
}
|
|
59
|
+
(_b = this.strict) !== null && _b !== void 0 ? _b : (this.strict = true);
|
|
42
60
|
}
|
|
43
61
|
}
|
|
44
62
|
exports.StoreParameters = StoreParameters;
|
|
@@ -79,8 +97,13 @@ exports.StoreParameters = StoreParameters;
|
|
|
79
97
|
class Store extends service_1.Service {
|
|
80
98
|
constructor() {
|
|
81
99
|
super(...arguments);
|
|
100
|
+
/**
|
|
101
|
+
* Contain the reverse map
|
|
102
|
+
*/
|
|
82
103
|
this._reverseMap = [];
|
|
83
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Contain the model uuid field
|
|
106
|
+
*/
|
|
84
107
|
this._uuidField = "uuid";
|
|
85
108
|
}
|
|
86
109
|
/**
|
|
@@ -98,31 +121,31 @@ class Store extends service_1.Service {
|
|
|
98
121
|
super.computeParameters();
|
|
99
122
|
const p = this.parameters;
|
|
100
123
|
this._model = this._webda.getModel(p.model);
|
|
101
|
-
if (!this._model) {
|
|
102
|
-
throw new Error(`${p.model} model is not found`);
|
|
103
|
-
}
|
|
104
124
|
this._uuidField = this._model.getUuidField();
|
|
105
|
-
this._lastUpdateField =
|
|
106
|
-
this._creationDateField =
|
|
125
|
+
this._lastUpdateField = this._model.getLastUpdateField();
|
|
126
|
+
this._creationDateField = this._model.getCreationField();
|
|
107
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Return Store current model
|
|
130
|
+
* @returns
|
|
131
|
+
*/
|
|
108
132
|
getModel() {
|
|
109
133
|
return this._model;
|
|
110
134
|
}
|
|
111
|
-
|
|
112
|
-
return this.
|
|
135
|
+
getLastUpdateField() {
|
|
136
|
+
return this._model.getLastUpdateField();
|
|
113
137
|
}
|
|
114
|
-
|
|
115
|
-
return
|
|
116
|
-
this.initMap(this.parameters.map);
|
|
117
|
-
if (this.parameters.index) {
|
|
118
|
-
yield this.createIndex();
|
|
119
|
-
}
|
|
120
|
-
});
|
|
138
|
+
getObject(uid) {
|
|
139
|
+
return this._get(uid);
|
|
121
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* @inheritdoc
|
|
143
|
+
*/
|
|
122
144
|
initRoutes() {
|
|
123
145
|
if (!this.parameters.expose) {
|
|
124
146
|
return;
|
|
125
147
|
}
|
|
148
|
+
// We enforce ExposeParameters within the constructor
|
|
126
149
|
const expose = this.parameters.expose;
|
|
127
150
|
if (!expose.restrict.create) {
|
|
128
151
|
this.addRoute(expose.url, ["POST"], this.httpCreate, {
|
|
@@ -155,7 +178,6 @@ class Store extends service_1.Service {
|
|
|
155
178
|
if (!expose.restrict.delete) {
|
|
156
179
|
methods.push("DELETE");
|
|
157
180
|
}
|
|
158
|
-
this._exposeUrl = expose.url;
|
|
159
181
|
if (methods.length) {
|
|
160
182
|
this.addRoute(expose.url + "/{uuid}", methods, this.httpRoute, {
|
|
161
183
|
model: this._model.name,
|
|
@@ -215,86 +237,77 @@ class Store extends service_1.Service {
|
|
|
215
237
|
let actions = this._model.getActions();
|
|
216
238
|
Object.keys(actions).forEach(name => {
|
|
217
239
|
let action = actions[name];
|
|
218
|
-
action.
|
|
219
|
-
|
|
220
|
-
throw Error("Action needs a name got:" + action);
|
|
221
|
-
}
|
|
222
|
-
if (!action.method) {
|
|
223
|
-
action.method = ["PUT"];
|
|
240
|
+
if (!action.methods) {
|
|
241
|
+
action.methods = ["PUT"];
|
|
224
242
|
}
|
|
243
|
+
let executer;
|
|
225
244
|
if (action.global) {
|
|
226
245
|
// By default will grab the object and then call the action
|
|
227
|
-
if (!
|
|
228
|
-
|
|
229
|
-
throw Error("Action static method _" + action.name + " does not exist");
|
|
230
|
-
}
|
|
231
|
-
action._method = this.httpGlobalAction;
|
|
246
|
+
if (!this._model["_" + name]) {
|
|
247
|
+
throw Error("Action static method _" + name + " does not exist");
|
|
232
248
|
}
|
|
233
|
-
|
|
249
|
+
executer = this.httpGlobalAction;
|
|
250
|
+
this.addRoute(expose.url + "/" + name, action.methods, executer, action.openapi);
|
|
234
251
|
}
|
|
235
252
|
else {
|
|
236
253
|
// By default will grab the object and then call the action
|
|
237
|
-
if (!
|
|
238
|
-
|
|
239
|
-
throw Error("Action method _" + action.name + " does not exist");
|
|
240
|
-
}
|
|
241
|
-
action._method = this.httpAction;
|
|
254
|
+
if (!this._model.prototype["_" + name]) {
|
|
255
|
+
throw Error("Action method _" + name + " does not exist");
|
|
242
256
|
}
|
|
243
|
-
|
|
257
|
+
executer = this.httpAction;
|
|
258
|
+
this.addRoute(expose.url + "/{uuid}/" + name, action.methods, executer, action.openapi);
|
|
244
259
|
}
|
|
245
260
|
});
|
|
246
261
|
}
|
|
247
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Get the url where the store is exposed
|
|
265
|
+
*/
|
|
248
266
|
getUrl() {
|
|
249
|
-
return this.
|
|
267
|
+
return this.parameters.expose.url;
|
|
250
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Init a model from the current stored data
|
|
271
|
+
*
|
|
272
|
+
* Initial the reverse map as well
|
|
273
|
+
*
|
|
274
|
+
* @param object
|
|
275
|
+
* @returns
|
|
276
|
+
*/
|
|
251
277
|
initModel(object = {}) {
|
|
278
|
+
var _a;
|
|
279
|
+
var _b;
|
|
252
280
|
// Make sure to send a model object
|
|
253
281
|
if (!(object instanceof this._model)) {
|
|
254
282
|
let model = new this._model();
|
|
255
283
|
model.load(object, true);
|
|
256
284
|
object = model;
|
|
257
285
|
}
|
|
286
|
+
if (!object.getUuid()) {
|
|
287
|
+
object.setUuid(object.generateUid(object));
|
|
288
|
+
}
|
|
258
289
|
object.__store = this;
|
|
259
290
|
for (var i in this._reverseMap) {
|
|
291
|
+
(_a = object[_b = this._reverseMap[i].property]) !== null && _a !== void 0 ? _a : (object[_b] = []);
|
|
260
292
|
for (var j in object[this._reverseMap[i].property]) {
|
|
261
|
-
|
|
293
|
+
// Use Partial
|
|
294
|
+
object[this._reverseMap[i].property][j] = this._reverseMap[i].mapper.initModel(object[this._reverseMap[i].property][j]);
|
|
262
295
|
object[this._reverseMap[i].property][j].setContext(object.getContext());
|
|
263
296
|
}
|
|
264
297
|
}
|
|
265
298
|
return object;
|
|
266
299
|
}
|
|
267
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Add reverse map information
|
|
302
|
+
*
|
|
303
|
+
* @param prop
|
|
304
|
+
* @param cascade
|
|
305
|
+
* @param store
|
|
306
|
+
*/
|
|
307
|
+
addReverseMap(prop, store) {
|
|
268
308
|
this._reverseMap.push({
|
|
269
309
|
property: prop,
|
|
270
|
-
|
|
271
|
-
});
|
|
272
|
-
if (cascade) {
|
|
273
|
-
this._cascade.push(cascade);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
isMapped(property) {
|
|
277
|
-
if (property === undefined) {
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
if (!this.parameters.map) {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
let map = this.parameters.map;
|
|
284
|
-
for (let prop in map) {
|
|
285
|
-
// No mapped property or not in the object
|
|
286
|
-
if (map[prop].key === undefined) {
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
if (map[prop].fields.split(",").indexOf(property) >= 0) {
|
|
290
|
-
return true;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
_incrementAttribute(uid, prop, value, updateDate) {
|
|
296
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
297
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
310
|
+
mapper: store
|
|
298
311
|
});
|
|
299
312
|
}
|
|
300
313
|
incrementAttribute(uid, prop, value) {
|
|
@@ -305,10 +318,10 @@ class Store extends service_1.Service {
|
|
|
305
318
|
}
|
|
306
319
|
let updateDate = new Date();
|
|
307
320
|
yield this._incrementAttribute(uid, prop, value, updateDate);
|
|
308
|
-
yield this._handleMapFromPartial(uid, updateDate, prop);
|
|
309
321
|
return this.emitSync("Store.PartialUpdated", {
|
|
310
322
|
object_id: uid,
|
|
311
323
|
store: this,
|
|
324
|
+
updateDate,
|
|
312
325
|
partial_update: {
|
|
313
326
|
increment: {
|
|
314
327
|
value: value,
|
|
@@ -325,10 +338,10 @@ class Store extends service_1.Service {
|
|
|
325
338
|
}
|
|
326
339
|
let updateDate = new Date();
|
|
327
340
|
yield this._upsertItemToCollection(uid, prop, item, index, itemWriteCondition, itemWriteConditionField, updateDate);
|
|
328
|
-
yield this._handleMapFromPartial(uid, updateDate);
|
|
329
341
|
yield this.emitSync("Store.PartialUpdated", {
|
|
330
342
|
object_id: uid,
|
|
331
343
|
store: this,
|
|
344
|
+
updateDate,
|
|
332
345
|
partial_update: {
|
|
333
346
|
addItem: {
|
|
334
347
|
value: item,
|
|
@@ -339,39 +352,14 @@ class Store extends service_1.Service {
|
|
|
339
352
|
});
|
|
340
353
|
});
|
|
341
354
|
}
|
|
342
|
-
|
|
355
|
+
deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField = this._uuidField) {
|
|
343
356
|
return __awaiter(this, void 0, void 0, function* () {
|
|
344
|
-
if (this.isMapped(prop) || this.isMapped(this._lastUpdateField)) {
|
|
345
|
-
// Not optimal need to reload the object
|
|
346
|
-
let object = yield this._get(uid);
|
|
347
|
-
let updates = {};
|
|
348
|
-
updates[this._lastUpdateField] = updateDate;
|
|
349
|
-
if (this.isMapped(prop)) {
|
|
350
|
-
updates[prop] = object.prop;
|
|
351
|
-
}
|
|
352
|
-
yield this.handleMap(object, this.parameters.map, updates);
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
_upsertItemToCollection(uid, prop, item, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
357
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
358
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField) {
|
|
362
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
363
|
-
if (index === undefined || prop === undefined) {
|
|
364
|
-
throw Error("Invalid Argument");
|
|
365
|
-
}
|
|
366
|
-
if (itemWriteConditionField === undefined) {
|
|
367
|
-
itemWriteConditionField = this._uuidField;
|
|
368
|
-
}
|
|
369
357
|
let updateDate = new Date();
|
|
370
358
|
yield this._deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField, updateDate);
|
|
371
|
-
yield this._handleMapFromPartial(uid, updateDate);
|
|
372
359
|
yield this.emitSync("Store.PartialUpdated", {
|
|
373
360
|
object_id: uid,
|
|
374
361
|
store: this,
|
|
362
|
+
updateDate,
|
|
375
363
|
partial_update: {
|
|
376
364
|
deleteItem: {
|
|
377
365
|
property: prop,
|
|
@@ -381,76 +369,26 @@ class Store extends service_1.Service {
|
|
|
381
369
|
});
|
|
382
370
|
});
|
|
383
371
|
}
|
|
384
|
-
_deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
385
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
386
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
createIndex() {
|
|
390
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
391
|
-
if (!this.parameters.index || (yield this.exists("index"))) {
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
let index = {};
|
|
395
|
-
index[this._uuidField] = "index";
|
|
396
|
-
index[this._lastUpdateField] = new Date();
|
|
397
|
-
yield this.save(index);
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
initMap(map) {
|
|
401
|
-
if (map == undefined || map._init) {
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
for (var prop in map) {
|
|
405
|
-
var reverseStore = this._webda.getService(prop);
|
|
406
|
-
if (reverseStore === undefined || !(reverseStore instanceof Store)) {
|
|
407
|
-
map[prop]["-onerror"] = "NoStore";
|
|
408
|
-
this.log("WARN", "Can't setup mapping as store \"", prop, "\" doesn't exist");
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
var cascade = undefined;
|
|
412
|
-
if (map[prop].cascade) {
|
|
413
|
-
cascade = {
|
|
414
|
-
store: this._name,
|
|
415
|
-
name: map[prop].target
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
reverseStore.addReverseMap(map[prop].target, cascade, this);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
toString() {
|
|
422
|
-
return this.parameters.type + "[" + this._name + "]";
|
|
423
|
-
}
|
|
424
|
-
generateUid() {
|
|
425
|
-
return uuid_1.v4();
|
|
426
|
-
}
|
|
427
372
|
/**
|
|
428
373
|
* Save an object
|
|
429
374
|
*
|
|
430
375
|
* @param {Object} Object to save
|
|
431
376
|
* @param {String} Uuid to use, if not specified take the object.uuid or generate one if not found
|
|
432
377
|
* @return {Promise} with saved object
|
|
378
|
+
*
|
|
379
|
+
* Might want to rename to create
|
|
433
380
|
*/
|
|
434
381
|
save(object, ctx = undefined) {
|
|
382
|
+
var _a;
|
|
383
|
+
var _b;
|
|
435
384
|
return __awaiter(this, void 0, void 0, function* () {
|
|
436
|
-
/** @ignore */
|
|
437
|
-
for (var i in this._reverseMap) {
|
|
438
|
-
if (object[this._reverseMap[i].property] === undefined) {
|
|
439
|
-
object[this._reverseMap[i].property] = [];
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
object[this._creationDateField] = object[this._lastUpdateField] = new Date();
|
|
443
385
|
object = this.initModel(object);
|
|
386
|
+
// Dates should be store by the Store
|
|
387
|
+
(_a = object[_b = this._creationDateField]) !== null && _a !== void 0 ? _a : (object[_b] = new Date());
|
|
388
|
+
object[this._lastUpdateField] = new Date();
|
|
444
389
|
if (ctx) {
|
|
445
390
|
object.setContext(ctx);
|
|
446
391
|
}
|
|
447
|
-
if (!object[this._uuidField]) {
|
|
448
|
-
object[this._uuidField] = object.generateUid();
|
|
449
|
-
object[this._creationDateField] = new Date();
|
|
450
|
-
if (!object[this._uuidField]) {
|
|
451
|
-
object[this._uuidField] = this.generateUid();
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
392
|
yield this.emitSync("Store.Save", {
|
|
455
393
|
object: object,
|
|
456
394
|
store: this
|
|
@@ -464,35 +402,68 @@ class Store extends service_1.Service {
|
|
|
464
402
|
store: this
|
|
465
403
|
});
|
|
466
404
|
yield object._onSaved();
|
|
467
|
-
if (this.parameters.map != undefined) {
|
|
468
|
-
yield this.handleMap(object, this.parameters.map, "created");
|
|
469
|
-
}
|
|
470
|
-
// Handle index
|
|
471
|
-
if (this.parameters.index && object[this._uuidField] !== "index" && object[this._uuidField]) {
|
|
472
|
-
yield this.handleIndex(object, "created");
|
|
473
|
-
}
|
|
474
405
|
return object;
|
|
475
406
|
});
|
|
476
407
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Patch an object
|
|
410
|
+
*
|
|
411
|
+
* @param object
|
|
412
|
+
* @param reverseMap
|
|
413
|
+
* @returns
|
|
414
|
+
*/
|
|
482
415
|
patch(object, reverseMap = true) {
|
|
483
416
|
return __awaiter(this, void 0, void 0, function* () {
|
|
484
417
|
return this.update(object, reverseMap, true);
|
|
485
418
|
});
|
|
486
419
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
420
|
+
/**
|
|
421
|
+
* Check if an UpdateCondition is met
|
|
422
|
+
* @param model
|
|
423
|
+
* @param conditionField
|
|
424
|
+
* @param condition
|
|
425
|
+
* @param uid
|
|
426
|
+
*/
|
|
427
|
+
checkUpdateCondition(model, conditionField, condition, uid) {
|
|
428
|
+
if (conditionField) {
|
|
429
|
+
if (model[conditionField] !== condition) {
|
|
430
|
+
throw new UpdateConditionFailError(uid ? uid : model.getUuid(), conditionField, condition);
|
|
491
431
|
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Check if an UpdateCondition is met
|
|
436
|
+
* @param model
|
|
437
|
+
* @param conditionField
|
|
438
|
+
* @param condition
|
|
439
|
+
* @param uid
|
|
440
|
+
*/
|
|
441
|
+
checkCollectionUpdateCondition(model, collection, conditionField, condition, index) {
|
|
442
|
+
// No index so addition to collection
|
|
443
|
+
if (index === null) {
|
|
444
|
+
// The condition must be length of the collection
|
|
445
|
+
if (!model[collection] || model[collection].length !== condition) {
|
|
446
|
+
throw new UpdateConditionFailError(model.getUuid(), collection, condition);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
else if (condition && model[collection][index][conditionField] !== condition) {
|
|
450
|
+
throw new UpdateConditionFailError(model.getUuid(), `${collection}[${index}].${conditionField}`, condition);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
*
|
|
455
|
+
* @param model
|
|
456
|
+
* @param prop
|
|
457
|
+
* @param item
|
|
458
|
+
* @param index
|
|
459
|
+
* @param itemWriteCondition
|
|
460
|
+
* @param itemWriteConditionField
|
|
461
|
+
* @param updateDate
|
|
462
|
+
*/
|
|
463
|
+
simulateUpsertItemToCollection(model, prop, item, updateDate, index, itemWriteCondition, itemWriteConditionField) {
|
|
464
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
465
|
+
this.checkCollectionUpdateCondition(model, prop, itemWriteConditionField, itemWriteCondition, index);
|
|
492
466
|
if (index === undefined) {
|
|
493
|
-
if (itemWriteCondition !== undefined && model[prop].length !== itemWriteCondition) {
|
|
494
|
-
throw Error("UpdateCondition not met");
|
|
495
|
-
}
|
|
496
467
|
if (model[prop] === undefined) {
|
|
497
468
|
model[prop] = [item];
|
|
498
469
|
}
|
|
@@ -501,9 +472,6 @@ class Store extends service_1.Service {
|
|
|
501
472
|
}
|
|
502
473
|
}
|
|
503
474
|
else {
|
|
504
|
-
if (itemWriteCondition && model[prop][index][itemWriteConditionField] != itemWriteCondition) {
|
|
505
|
-
throw Error("UpdateCondition not met");
|
|
506
|
-
}
|
|
507
475
|
model[prop][index] = item;
|
|
508
476
|
}
|
|
509
477
|
model[this._lastUpdateField] = updateDate;
|
|
@@ -531,16 +499,18 @@ class Store extends service_1.Service {
|
|
|
531
499
|
}
|
|
532
500
|
}
|
|
533
501
|
let partialEvent = partial ? "Patch" : "";
|
|
534
|
-
if (Object.keys(object).length
|
|
502
|
+
if (Object.keys(object).length < 2) {
|
|
535
503
|
return {};
|
|
536
504
|
}
|
|
537
505
|
object[this._lastUpdateField] = new Date();
|
|
538
|
-
let load = yield this._get(object[this._uuidField]);
|
|
506
|
+
let load = yield this._get(object[this._uuidField], true);
|
|
507
|
+
if (load.__type !== this._model.name && this.parameters.strict) {
|
|
508
|
+
this.log("WARN", `Object '${object[this._uuidField]}' was not created by this store`);
|
|
509
|
+
throw new StoreNotFoundError(object[this._uuidField], this.getName());
|
|
510
|
+
}
|
|
539
511
|
loaded = this.initModel(load);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
if (this.parameters.index && loaded[this._uuidField] !== "index" && loaded[this._uuidField]) {
|
|
543
|
-
yield this.handleIndex(loaded, object);
|
|
512
|
+
if (object instanceof coremodel_1.CoreModel) {
|
|
513
|
+
loaded.setContext(object.getContext());
|
|
544
514
|
}
|
|
545
515
|
yield this.emitSync(`Store.${partialEvent}Update`, {
|
|
546
516
|
object: loaded,
|
|
@@ -576,241 +546,45 @@ class Store extends service_1.Service {
|
|
|
576
546
|
return saved;
|
|
577
547
|
});
|
|
578
548
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
removeMapper(map, uuid) {
|
|
588
|
-
let i = this.getMapper(map, uuid);
|
|
589
|
-
if (i >= 0) {
|
|
590
|
-
map.splice(i, 1);
|
|
591
|
-
return true;
|
|
592
|
-
}
|
|
593
|
-
return false;
|
|
594
|
-
}
|
|
595
|
-
_handleUpdatedMap(object, map, mapped, store, updates) {
|
|
596
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
597
|
-
var mapper = {};
|
|
598
|
-
mapper[this._uuidField] = object[this._uuidField];
|
|
599
|
-
// Update only if the key field has been updated
|
|
600
|
-
var found = false;
|
|
601
|
-
for (var field in updates) {
|
|
602
|
-
if (map.fields) {
|
|
603
|
-
let fields = map.fields.split(",");
|
|
604
|
-
for (let i in fields) {
|
|
605
|
-
let mapperfield = fields[i];
|
|
606
|
-
// Create the mapper object
|
|
607
|
-
if (updates[mapperfield] !== undefined) {
|
|
608
|
-
mapper[mapperfield] = updates[mapperfield];
|
|
609
|
-
found = true;
|
|
610
|
-
}
|
|
611
|
-
else if (object[mapperfield] !== undefined) {
|
|
612
|
-
mapper[mapperfield] = object[mapperfield];
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
// TODO Need to verify also if fields are updated
|
|
617
|
-
if (field == map.key) {
|
|
618
|
-
found = true;
|
|
619
|
-
break;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
if (!found) {
|
|
623
|
-
// None of the mapped keys has been modified -> return
|
|
624
|
-
return;
|
|
625
|
-
}
|
|
626
|
-
// check if reference object has changed
|
|
627
|
-
if (updates[map.key] != undefined && mapped[this._uuidField] != updates[map.key]) {
|
|
628
|
-
// create mapper
|
|
629
|
-
if (map.fields) {
|
|
630
|
-
let fields = map.fields.split(",");
|
|
631
|
-
for (var j in fields) {
|
|
632
|
-
let mapperfield = fields[j];
|
|
633
|
-
// Create the mapper object
|
|
634
|
-
if (updates[mapperfield] !== undefined) {
|
|
635
|
-
mapper[mapperfield] = updates[mapperfield];
|
|
636
|
-
}
|
|
637
|
-
else if (object[mapperfield] !== undefined) {
|
|
638
|
-
mapper[mapperfield] = object[mapperfield];
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
let i = this.getMapper(mapped[map.target], object[this._uuidField]);
|
|
643
|
-
if (i >= 0) {
|
|
644
|
-
// Remove the data from old object
|
|
645
|
-
yield store.deleteItemFromCollection(mapped[this._uuidField], map.target, i, object[this._uuidField], this._uuidField);
|
|
646
|
-
}
|
|
647
|
-
// Add the data to new object
|
|
648
|
-
yield store.upsertItemToCollection(updates[map.key], map.target, mapper);
|
|
649
|
-
}
|
|
650
|
-
else {
|
|
651
|
-
return this._handleUpdatedMapMapper(object, map, mapped, store, updates);
|
|
652
|
-
}
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
_handleUpdatedMapTransferOut(object, map, mapped, store, updates) {
|
|
656
|
-
var update = {};
|
|
657
|
-
update[map.target] = mapped[map.target];
|
|
658
|
-
return store.update(update, mapped[this._uuidField], false).then(() => {
|
|
659
|
-
return this._handleUpdatedMapTransferIn(object, map, store, updates);
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
_handleUpdatedMapTransferIn(object, map, store, updates) {
|
|
663
|
-
// TODO Should be update
|
|
664
|
-
return store.get(updates[map.key]).then(mapped => {
|
|
665
|
-
if (mapped == undefined) {
|
|
666
|
-
return Promise.resolve();
|
|
667
|
-
}
|
|
668
|
-
// Enforce the collection if needed
|
|
669
|
-
if (mapped[map.target] == undefined) {
|
|
670
|
-
mapped[map.target] = [];
|
|
671
|
-
}
|
|
672
|
-
return this._handleUpdatedMapMapper(object, map, mapped, store, updates);
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
_handleUpdatedMapMapper(object, map, mapped, store, updates) {
|
|
676
|
-
// Update the mapper
|
|
677
|
-
var mapper = {};
|
|
678
|
-
mapper[this._uuidField] = object[this._uuidField];
|
|
679
|
-
if (map.fields) {
|
|
680
|
-
var fields = map.fields.split(",");
|
|
681
|
-
for (var field in fields) {
|
|
682
|
-
if (updates[fields[field]] != undefined) {
|
|
683
|
-
mapper[fields[field]] = updates[fields[field]];
|
|
684
|
-
}
|
|
685
|
-
else {
|
|
686
|
-
mapper[fields[field]] = object[fields[field]];
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
// Remove old reference
|
|
691
|
-
let i = this.getMapper(mapped[map.target], object[this._uuidField]);
|
|
692
|
-
// If not found just add it to the collection
|
|
693
|
-
if (i < 0) {
|
|
694
|
-
return store.upsertItemToCollection(mapped[this._uuidField], map.target, mapper);
|
|
695
|
-
}
|
|
696
|
-
// Else update with a check on the uuid
|
|
697
|
-
return store.upsertItemToCollection(mapped[this._uuidField], map.target, mapper, i, object[this._uuidField], this._uuidField);
|
|
698
|
-
}
|
|
699
|
-
_handleDeletedMap(object, map, mapped, store) {
|
|
700
|
-
// Remove from the collection
|
|
701
|
-
if (mapped[map.target] === undefined) {
|
|
702
|
-
return Promise.resolve();
|
|
703
|
-
}
|
|
704
|
-
let i = this.getMapper(mapped[map.target], object[this._uuidField]);
|
|
705
|
-
if (i >= 0) {
|
|
706
|
-
return store.deleteItemFromCollection(mapped[this._uuidField], map.target, i, object[this._uuidField], this._uuidField);
|
|
707
|
-
}
|
|
708
|
-
return Promise.resolve();
|
|
709
|
-
}
|
|
710
|
-
_handleCreatedMap(object, map, mapped, store) {
|
|
711
|
-
// Add to the object
|
|
712
|
-
var mapper = {};
|
|
713
|
-
mapper[this._uuidField] = object[this._uuidField];
|
|
714
|
-
// Add info to the mapped
|
|
715
|
-
if (map.fields) {
|
|
716
|
-
var fields = map.fields.split(",");
|
|
717
|
-
for (var field in fields) {
|
|
718
|
-
mapper[fields[field]] = object[fields[field]];
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
return store.upsertItemToCollection(mapped[this._uuidField], map.target, mapper);
|
|
722
|
-
}
|
|
723
|
-
_handleMapProperty(store, object, property, updates) {
|
|
724
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
725
|
-
let mapped = yield store.get(object[property.key] || updates[property.key]);
|
|
726
|
-
if (mapped == undefined) {
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
if (updates === "created") {
|
|
730
|
-
return this._handleCreatedMap(object, property, mapped, store);
|
|
731
|
-
}
|
|
732
|
-
else if (updates == "deleted") {
|
|
733
|
-
return this._handleDeletedMap(object, property, mapped, store);
|
|
734
|
-
}
|
|
735
|
-
else if (typeof updates == "object") {
|
|
736
|
-
return this._handleUpdatedMap(object, property, mapped, store, updates);
|
|
737
|
-
}
|
|
738
|
-
else {
|
|
739
|
-
return Promise.reject(Error("Unknown handleMap type " + updates));
|
|
740
|
-
}
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
removeAttribute(uuid, attribute) {
|
|
744
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
745
|
-
return this._removeAttribute(uuid, attribute);
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
handleIndex(object, updates) {
|
|
549
|
+
/**
|
|
550
|
+
* Remove an attribute from an object
|
|
551
|
+
*
|
|
552
|
+
* @param uuid
|
|
553
|
+
* @param attribute
|
|
554
|
+
* @returns
|
|
555
|
+
*/
|
|
556
|
+
removeAttribute(uuid, attribute, itemWriteCondition, itemWriteConditionField) {
|
|
749
557
|
return __awaiter(this, void 0, void 0, function* () {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
toUpdate = true;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
if (!toUpdate) {
|
|
759
|
-
return;
|
|
558
|
+
yield this._removeAttribute(uuid, attribute, itemWriteCondition, itemWriteConditionField);
|
|
559
|
+
yield this.emitSync("Store.PartialUpdated", {
|
|
560
|
+
object_id: uuid,
|
|
561
|
+
partial_update: {
|
|
562
|
+
deleteAttribute: attribute
|
|
760
563
|
}
|
|
761
|
-
}
|
|
762
|
-
else if (updates === "deleted") {
|
|
763
|
-
yield this.removeAttribute("index", object[this._uuidField]);
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
else if (updates === "created") {
|
|
767
|
-
updates = object;
|
|
768
|
-
}
|
|
769
|
-
let mapper = {};
|
|
770
|
-
this.parameters.index.forEach(id => {
|
|
771
|
-
mapper[id] = updates[id];
|
|
772
564
|
});
|
|
773
|
-
mapUpdates[object[this._uuidField]] = mapper;
|
|
774
|
-
mapUpdates[this._lastUpdateField] = new Date();
|
|
775
|
-
yield this._patch(mapUpdates, "index");
|
|
776
565
|
});
|
|
777
566
|
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if (map[prop].key === undefined ||
|
|
787
|
-
(object[map[prop].key] === undefined && updates[map[prop].key] === undefined)) {
|
|
788
|
-
continue;
|
|
789
|
-
}
|
|
790
|
-
let store = this.getService(prop);
|
|
791
|
-
// Cant find the store for this collection
|
|
792
|
-
if (store == undefined) {
|
|
793
|
-
continue;
|
|
794
|
-
}
|
|
795
|
-
promises.push(this._handleMapProperty(store, object, map[prop], updates));
|
|
796
|
-
}
|
|
797
|
-
return Promise.all(promises);
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
_update(object, uid, itemWriteCondition = undefined, itemWriteConditionField = undefined) {
|
|
801
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
802
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
_patch(object, uid, itemWriteCondition = undefined, itemWriteConditionField = undefined) {
|
|
567
|
+
/**
|
|
568
|
+
* Cascade delete a related object
|
|
569
|
+
*
|
|
570
|
+
* @param obj
|
|
571
|
+
* @param uuid
|
|
572
|
+
* @returns
|
|
573
|
+
*/
|
|
574
|
+
cascadeDelete(obj, uuid) {
|
|
806
575
|
return __awaiter(this, void 0, void 0, function* () {
|
|
807
|
-
|
|
576
|
+
// We dont need uuid but Binary store will need it
|
|
577
|
+
return this.delete(obj.getUuid());
|
|
808
578
|
});
|
|
809
579
|
}
|
|
810
|
-
|
|
580
|
+
/**
|
|
581
|
+
* Delete an object from the store without condition nor async
|
|
582
|
+
* @param uid to delete
|
|
583
|
+
* @returns
|
|
584
|
+
*/
|
|
585
|
+
forceDelete(uid) {
|
|
811
586
|
return __awaiter(this, void 0, void 0, function* () {
|
|
812
|
-
|
|
813
|
-
return this.delete(obj[this._uuidField]);
|
|
587
|
+
return this.delete(uid, undefined, undefined, true);
|
|
814
588
|
});
|
|
815
589
|
}
|
|
816
590
|
/**
|
|
@@ -820,58 +594,48 @@ class Store extends service_1.Service {
|
|
|
820
594
|
* @param {Boolean} delete sync even if asyncDelete is active
|
|
821
595
|
* @return {Promise} the deletion promise
|
|
822
596
|
*/
|
|
823
|
-
delete(uid, sync = false) {
|
|
597
|
+
delete(uid, writeCondition, writeConditionField, sync = false) {
|
|
824
598
|
return __awaiter(this, void 0, void 0, function* () {
|
|
825
599
|
/** @ignore */
|
|
826
600
|
let to_delete;
|
|
601
|
+
// Allow full object or just its uuid
|
|
827
602
|
if (typeof uid === "object") {
|
|
828
603
|
to_delete = uid;
|
|
829
|
-
uid = to_delete[this._uuidField];
|
|
830
|
-
if (!(to_delete instanceof this._model)) {
|
|
831
|
-
to_delete = this.initModel(yield this._get(uid));
|
|
832
|
-
}
|
|
833
604
|
}
|
|
834
605
|
else {
|
|
835
|
-
to_delete =
|
|
606
|
+
to_delete = yield this._get(uid);
|
|
607
|
+
if (to_delete === undefined) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
if (to_delete.__type !== this._model.name && this.parameters.strict) {
|
|
611
|
+
this.log("WARN", `Object '${uid}' was not created by this store`);
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
to_delete = this.initModel(to_delete);
|
|
836
615
|
}
|
|
837
|
-
|
|
838
|
-
|
|
616
|
+
// Check condition as we have the object
|
|
617
|
+
if (writeCondition) {
|
|
618
|
+
if (to_delete[writeConditionField] !== writeCondition) {
|
|
619
|
+
throw new UpdateConditionFailError(to_delete.getUuid(), writeConditionField, writeCondition);
|
|
620
|
+
}
|
|
839
621
|
}
|
|
622
|
+
// Send preevent
|
|
840
623
|
yield this.emitSync("Store.Delete", {
|
|
841
624
|
object: to_delete,
|
|
842
625
|
store: this
|
|
843
626
|
});
|
|
844
627
|
yield to_delete._onDelete();
|
|
845
|
-
|
|
846
|
-
yield this.handleMap(to_delete, this.parameters.map, "deleted");
|
|
847
|
-
}
|
|
848
|
-
// Handle index
|
|
849
|
-
if (this.parameters.index && to_delete[this._uuidField] !== "index" && to_delete[this._uuidField]) {
|
|
850
|
-
yield this.handleIndex(to_delete, "deleted");
|
|
851
|
-
}
|
|
852
|
-
if (this._cascade != undefined && to_delete !== undefined) {
|
|
853
|
-
var promises = [];
|
|
854
|
-
// Should deactiate the mapping in that case
|
|
855
|
-
for (let i in this._cascade) {
|
|
856
|
-
if (typeof this._cascade[i] != "object" || to_delete[this._cascade[i].name] == undefined)
|
|
857
|
-
continue;
|
|
858
|
-
var targetStore = this.getService(this._cascade[i].store);
|
|
859
|
-
if (targetStore == undefined)
|
|
860
|
-
continue;
|
|
861
|
-
for (var item in to_delete[this._cascade[i].name]) {
|
|
862
|
-
promises.push(targetStore.cascadeDelete(to_delete[this._cascade[i].name][item], to_delete[this._uuidField]));
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
yield Promise.all(promises);
|
|
866
|
-
}
|
|
628
|
+
// If async we just tag the object as deleted
|
|
867
629
|
if (this.parameters.asyncDelete && !sync) {
|
|
868
630
|
yield this._patch({
|
|
869
631
|
__deleted: true
|
|
870
|
-
},
|
|
632
|
+
}, to_delete.getUuid());
|
|
871
633
|
}
|
|
872
634
|
else {
|
|
873
|
-
|
|
635
|
+
// Delete from the DB for real
|
|
636
|
+
yield this._delete(to_delete.getUuid(), writeCondition, writeConditionField);
|
|
874
637
|
}
|
|
638
|
+
// Send post event
|
|
875
639
|
yield this.emitSync("Store.Deleted", {
|
|
876
640
|
object: to_delete,
|
|
877
641
|
store: this
|
|
@@ -879,37 +643,6 @@ class Store extends service_1.Service {
|
|
|
879
643
|
yield to_delete._onDeleted();
|
|
880
644
|
});
|
|
881
645
|
}
|
|
882
|
-
/**
|
|
883
|
-
* Check if an object exists
|
|
884
|
-
* @abstract
|
|
885
|
-
* @params {String} uuid of the object
|
|
886
|
-
*/
|
|
887
|
-
exists(uid) {
|
|
888
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
889
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
_delete(uid, writeCondition, itemWriteConditionField) {
|
|
893
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
894
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
_get(uid) {
|
|
898
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
899
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
900
|
-
});
|
|
901
|
-
}
|
|
902
|
-
/**
|
|
903
|
-
* Get an object
|
|
904
|
-
*
|
|
905
|
-
* @param {Array} uuid to gets if undefined then retrieve the all table
|
|
906
|
-
* @return {Promise} the objects retrieved ( can be [] if not found )
|
|
907
|
-
*/
|
|
908
|
-
getAll(list = undefined) {
|
|
909
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
910
|
-
throw Error("Virtual abstract class - concrete only for MixIn usage");
|
|
911
|
-
});
|
|
912
|
-
}
|
|
913
646
|
/**
|
|
914
647
|
* By default we cannot know if the store will trigger or not
|
|
915
648
|
*
|
|
@@ -930,7 +663,7 @@ class Store extends service_1.Service {
|
|
|
930
663
|
if (!object) {
|
|
931
664
|
return undefined;
|
|
932
665
|
}
|
|
933
|
-
let result =
|
|
666
|
+
let result = {};
|
|
934
667
|
for (let i in object) {
|
|
935
668
|
if (i === this._uuidField || i === this._lastUpdateField || i.startsWith("_")) {
|
|
936
669
|
continue;
|
|
@@ -956,6 +689,10 @@ class Store extends service_1.Service {
|
|
|
956
689
|
if (!object) {
|
|
957
690
|
return undefined;
|
|
958
691
|
}
|
|
692
|
+
if (object.__type !== this._model.name && this.parameters.strict) {
|
|
693
|
+
this.log("WARN", `Object '${uid}' was not created by this store`);
|
|
694
|
+
return undefined;
|
|
695
|
+
}
|
|
959
696
|
object = this.initModel(object);
|
|
960
697
|
object.setContext(ctx);
|
|
961
698
|
yield this.emitSync("Store.Get", {
|
|
@@ -966,6 +703,34 @@ class Store extends service_1.Service {
|
|
|
966
703
|
return object;
|
|
967
704
|
});
|
|
968
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* Set one attribute in an object
|
|
708
|
+
*
|
|
709
|
+
* this is an helper function that calls patch
|
|
710
|
+
*
|
|
711
|
+
* @param uid of the object
|
|
712
|
+
* @param property to update1
|
|
713
|
+
* @param value new value
|
|
714
|
+
* @returns
|
|
715
|
+
*/
|
|
716
|
+
setAttribute(uid, property, value) {
|
|
717
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
718
|
+
let patch = {};
|
|
719
|
+
patch[property] = value;
|
|
720
|
+
patch[this.getUuidField()] = uid;
|
|
721
|
+
yield this.patch(patch);
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Search inside the store
|
|
726
|
+
*
|
|
727
|
+
* Still need to define a good abstraction for it
|
|
728
|
+
*
|
|
729
|
+
* @param request
|
|
730
|
+
* @param offset
|
|
731
|
+
* @param limit
|
|
732
|
+
* @returns
|
|
733
|
+
*/
|
|
969
734
|
find(request = undefined, offset = 0, limit = undefined) {
|
|
970
735
|
return __awaiter(this, void 0, void 0, function* () {
|
|
971
736
|
yield this.emitSync("Store.Find", {
|
|
@@ -985,12 +750,10 @@ class Store extends service_1.Service {
|
|
|
985
750
|
return result;
|
|
986
751
|
});
|
|
987
752
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
// ADD THE EXECUTOR PART
|
|
753
|
+
/**
|
|
754
|
+
* Handle POST
|
|
755
|
+
* @param ctx
|
|
756
|
+
*/
|
|
994
757
|
httpCreate(ctx) {
|
|
995
758
|
return __awaiter(this, void 0, void 0, function* () {
|
|
996
759
|
let body = ctx.getRequestBody();
|
|
@@ -1019,14 +782,14 @@ class Store extends service_1.Service {
|
|
|
1019
782
|
});
|
|
1020
783
|
});
|
|
1021
784
|
}
|
|
785
|
+
/**
|
|
786
|
+
* Handle obect action
|
|
787
|
+
* @param ctx
|
|
788
|
+
*/
|
|
1022
789
|
httpAction(ctx) {
|
|
1023
790
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1024
791
|
let action = ctx.getHttpContext().getUrl().split("/").pop();
|
|
1025
|
-
let
|
|
1026
|
-
if (!uuid) {
|
|
1027
|
-
throw 400;
|
|
1028
|
-
}
|
|
1029
|
-
let object = yield this.get(uuid, ctx);
|
|
792
|
+
let object = yield this.get(ctx.parameter("uuid"), ctx);
|
|
1030
793
|
if (object === undefined || object.__deleted) {
|
|
1031
794
|
throw 404;
|
|
1032
795
|
}
|
|
@@ -1050,6 +813,10 @@ class Store extends service_1.Service {
|
|
|
1050
813
|
});
|
|
1051
814
|
});
|
|
1052
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* Handle collection action
|
|
818
|
+
* @param ctx
|
|
819
|
+
*/
|
|
1053
820
|
httpGlobalAction(ctx) {
|
|
1054
821
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1055
822
|
let action = ctx.getHttpContext().getUrl().split("/").pop();
|
|
@@ -1084,15 +851,22 @@ class Store extends service_1.Service {
|
|
|
1084
851
|
if (!object || object.__deleted)
|
|
1085
852
|
throw 404;
|
|
1086
853
|
yield object.canAct(ctx, "update");
|
|
1087
|
-
try {
|
|
1088
|
-
yield object.validate(ctx, body);
|
|
1089
|
-
}
|
|
1090
|
-
catch (err) {
|
|
1091
|
-
this.log("INFO", "Object invalid", err);
|
|
1092
|
-
throw 400;
|
|
1093
|
-
}
|
|
1094
854
|
if (ctx.getHttpContext().getMethod() === "PATCH") {
|
|
855
|
+
try {
|
|
856
|
+
yield object.validate(ctx, body);
|
|
857
|
+
}
|
|
858
|
+
catch (err) {
|
|
859
|
+
this.log("INFO", "Object invalid", err);
|
|
860
|
+
throw 400;
|
|
861
|
+
}
|
|
1095
862
|
let updateObject = new this._model();
|
|
863
|
+
// Clean any default attributes from the model
|
|
864
|
+
for (let i in updateObject) {
|
|
865
|
+
if (i.startsWith("__")) {
|
|
866
|
+
continue;
|
|
867
|
+
}
|
|
868
|
+
delete updateObject[i];
|
|
869
|
+
}
|
|
1096
870
|
updateObject.setContext(ctx);
|
|
1097
871
|
updateObject.load(body);
|
|
1098
872
|
yield this.patch(updateObject);
|
|
@@ -1107,6 +881,13 @@ class Store extends service_1.Service {
|
|
|
1107
881
|
updateObject[i] = object[i];
|
|
1108
882
|
}
|
|
1109
883
|
}
|
|
884
|
+
try {
|
|
885
|
+
yield updateObject.validate(ctx);
|
|
886
|
+
}
|
|
887
|
+
catch (err) {
|
|
888
|
+
this.log("INFO", "Object invalid", err);
|
|
889
|
+
throw 400;
|
|
890
|
+
}
|
|
1110
891
|
// Add mappers back to
|
|
1111
892
|
object = yield this.update(updateObject);
|
|
1112
893
|
}
|
|
@@ -1130,6 +911,11 @@ class Store extends service_1.Service {
|
|
|
1130
911
|
let uuid = ctx.parameter("uuid");
|
|
1131
912
|
if (uuid) {
|
|
1132
913
|
let object = yield this.get(uuid, ctx);
|
|
914
|
+
yield this.emitSync("Store.WebGetNotFound", {
|
|
915
|
+
context: ctx,
|
|
916
|
+
uuid,
|
|
917
|
+
store: this
|
|
918
|
+
});
|
|
1133
919
|
if (object === undefined || object.__deleted) {
|
|
1134
920
|
throw 404;
|
|
1135
921
|
}
|
|
@@ -1180,6 +966,12 @@ class Store extends service_1.Service {
|
|
|
1180
966
|
}
|
|
1181
967
|
});
|
|
1182
968
|
}
|
|
969
|
+
/**
|
|
970
|
+
* Return the model uuid field
|
|
971
|
+
*/
|
|
972
|
+
getUuidField() {
|
|
973
|
+
return this._uuidField;
|
|
974
|
+
}
|
|
1183
975
|
}
|
|
1184
976
|
exports.Store = Store;
|
|
1185
977
|
//# sourceMappingURL=store.js.map
|