@webda/core 2.4.2 → 3.0.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 +171 -34
- package/lib/application.js +243 -47
- package/lib/application.js.map +1 -1
- package/lib/application.spec.js +44 -8
- package/lib/application.spec.js.map +1 -1
- package/lib/core.d.ts +113 -54
- package/lib/core.js +222 -135
- package/lib/core.js.map +1 -1
- package/lib/core.spec.js +87 -43
- package/lib/core.spec.js.map +1 -1
- package/lib/errors.d.ts +65 -0
- package/lib/errors.js +113 -0
- package/lib/errors.js.map +1 -0
- package/lib/errors.spec.d.ts +1 -0
- package/lib/errors.spec.js +33 -0
- package/lib/errors.spec.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/models/aclmodel.d.ts +4 -4
- package/lib/models/aclmodel.js +10 -6
- package/lib/models/aclmodel.js.map +1 -1
- package/lib/models/aclmodel.spec.js +33 -24
- package/lib/models/aclmodel.spec.js.map +1 -1
- package/lib/models/coremodel.d.ts +284 -92
- package/lib/models/coremodel.js +403 -103
- package/lib/models/coremodel.js.map +1 -1
- package/lib/models/coremodel.spec.js +162 -24
- package/lib/models/coremodel.spec.js.map +1 -1
- package/lib/models/ident.d.ts +20 -6
- package/lib/models/ident.js.map +1 -1
- package/lib/models/ownermodel.d.ts +13 -23
- package/lib/models/ownermodel.js +24 -51
- package/lib/models/ownermodel.js.map +1 -1
- package/lib/models/ownermodel.spec.js +23 -11
- package/lib/models/ownermodel.spec.js.map +1 -1
- package/lib/models/relations.d.ts +167 -0
- package/lib/models/relations.js +113 -0
- package/lib/models/relations.js.map +1 -0
- package/lib/models/rolemodel.d.ts +3 -3
- package/lib/models/rolemodel.js +6 -6
- package/lib/models/rolemodel.js.map +1 -1
- package/lib/models/rolemodel.spec.js +12 -12
- package/lib/models/rolemodel.spec.js.map +1 -1
- package/lib/models/user.d.ts +40 -24
- package/lib/models/user.js +74 -48
- package/lib/models/user.js.map +1 -1
- package/lib/models/user.spec.js +24 -4
- package/lib/models/user.spec.js.map +1 -1
- package/lib/queues/memoryqueue.spec.js +9 -5
- package/lib/queues/memoryqueue.spec.js.map +1 -1
- package/lib/queues/queueservice.js.map +1 -1
- package/lib/router.d.ts +17 -8
- package/lib/router.js +81 -9
- package/lib/router.js.map +1 -1
- package/lib/router.spec.js +89 -5
- package/lib/router.spec.js.map +1 -1
- package/lib/services/asyncevents.spec.js +4 -4
- package/lib/services/authentication.d.ts +21 -22
- package/lib/services/authentication.js +90 -109
- package/lib/services/authentication.js.map +1 -1
- package/lib/services/authentication.spec.js +51 -65
- package/lib/services/authentication.spec.js.map +1 -1
- package/lib/services/binary.d.ts +132 -31
- package/lib/services/binary.js +257 -72
- package/lib/services/binary.js.map +1 -1
- package/lib/services/binary.spec.d.ts +16 -6
- package/lib/services/binary.spec.js +44 -117
- package/lib/services/binary.spec.js.map +1 -1
- package/lib/services/cloudbinary.d.ts +9 -10
- package/lib/services/cloudbinary.js +14 -15
- package/lib/services/cloudbinary.js.map +1 -1
- package/lib/services/cloudbinary.spec.d.ts +2 -2
- package/lib/services/cloudbinary.spec.js +13 -12
- package/lib/services/cloudbinary.spec.js.map +1 -1
- package/lib/services/configuration.js +9 -9
- package/lib/services/configuration.js.map +1 -1
- package/lib/services/configuration.spec.js +5 -7
- package/lib/services/configuration.spec.js.map +1 -1
- package/lib/services/cron.spec.js +3 -4
- package/lib/services/cron.spec.js.map +1 -1
- package/lib/services/cryptoservice.d.ts +2 -2
- package/lib/services/cryptoservice.js +5 -2
- package/lib/services/cryptoservice.js.map +1 -1
- package/lib/services/domainservice.d.ts +113 -0
- package/lib/services/domainservice.js +357 -0
- package/lib/services/domainservice.js.map +1 -0
- package/lib/services/domainservice.spec.d.ts +1 -0
- package/lib/services/domainservice.spec.js +334 -0
- package/lib/services/domainservice.spec.js.map +1 -0
- package/lib/services/echo.d.ts +2 -2
- package/lib/services/echo.js.map +1 -1
- package/lib/services/echo.spec.js +9 -2
- package/lib/services/echo.spec.js.map +1 -1
- package/lib/services/filebinary.d.ts +13 -14
- package/lib/services/filebinary.js +79 -73
- package/lib/services/filebinary.js.map +1 -1
- package/lib/services/filebinary.spec.d.ts +5 -0
- package/lib/services/filebinary.spec.js +222 -11
- package/lib/services/filebinary.spec.js.map +1 -1
- package/lib/services/fileconfiguration.js +4 -4
- package/lib/services/fileconfiguration.js.map +1 -1
- package/lib/services/fileconfiguration.spec.js +23 -24
- package/lib/services/fileconfiguration.spec.js.map +1 -1
- package/lib/services/invitationservice.d.ts +11 -9
- package/lib/services/invitationservice.js +17 -23
- package/lib/services/invitationservice.js.map +1 -1
- package/lib/services/invitationservice.spec.js +43 -40
- package/lib/services/invitationservice.spec.js.map +1 -1
- package/lib/services/kubernetesconfiguration.js +12 -22
- package/lib/services/kubernetesconfiguration.js.map +1 -1
- package/lib/services/kubernetesconfiguration.spec.js +1 -6
- package/lib/services/kubernetesconfiguration.spec.js.map +1 -1
- package/lib/services/mailer.js +1 -1
- package/lib/services/mailer.js.map +1 -1
- package/lib/services/mailer.spec.js +4 -1
- package/lib/services/mailer.spec.js.map +1 -1
- package/lib/services/oauth.d.ts +17 -9
- package/lib/services/oauth.js +30 -4
- package/lib/services/oauth.js.map +1 -1
- package/lib/services/oauth.spec.js +32 -15
- package/lib/services/oauth.spec.js.map +1 -1
- package/lib/services/prometheus.spec.js.map +1 -1
- package/lib/services/proxy.d.ts +9 -8
- package/lib/services/proxy.js +65 -36
- package/lib/services/proxy.js.map +1 -1
- package/lib/services/proxy.spec.js +28 -2
- package/lib/services/proxy.spec.js.map +1 -1
- package/lib/services/resource.d.ts +3 -3
- package/lib/services/resource.js +4 -3
- package/lib/services/resource.js.map +1 -1
- package/lib/services/resource.spec.js +3 -3
- package/lib/services/resource.spec.js.map +1 -1
- package/lib/services/service.d.ts +10 -13
- package/lib/services/service.js +29 -13
- package/lib/services/service.js.map +1 -1
- package/lib/services/service.spec.js +49 -11
- package/lib/services/service.spec.js.map +1 -1
- package/lib/services/version.d.ts +2 -2
- package/lib/services/version.js.map +1 -1
- package/lib/stores/aggregator.js +1 -0
- package/lib/stores/aggregator.js.map +1 -1
- package/lib/stores/aliasstore.d.ts +2 -2
- package/lib/stores/aliasstore.js +15 -4
- package/lib/stores/aliasstore.js.map +1 -1
- package/lib/stores/aliasstore.spec.js +4 -2
- package/lib/stores/aliasstore.spec.js.map +1 -1
- package/lib/stores/file.d.ts +5 -2
- package/lib/stores/file.js +11 -8
- package/lib/stores/file.js.map +1 -1
- package/lib/stores/file.spec.js +21 -34
- package/lib/stores/file.spec.js.map +1 -1
- package/lib/stores/mapper.d.ts +4 -2
- package/lib/stores/mapper.js +18 -11
- package/lib/stores/mapper.js.map +1 -1
- package/lib/stores/mapper.spec.js +6 -3
- package/lib/stores/mapper.spec.js.map +1 -1
- package/lib/stores/memory.d.ts +5 -2
- package/lib/stores/memory.js +11 -9
- package/lib/stores/memory.js.map +1 -1
- package/lib/stores/memory.spec.d.ts +3 -0
- package/lib/stores/memory.spec.js +100 -11
- package/lib/stores/memory.spec.js.map +1 -1
- package/lib/stores/store.d.ts +177 -87
- package/lib/stores/store.js +312 -141
- package/lib/stores/store.js.map +1 -1
- package/lib/stores/store.spec.d.ts +2 -2
- package/lib/stores/store.spec.js +54 -38
- package/lib/stores/store.spec.js.map +1 -1
- package/lib/stores/webdaql/WebdaQLLexer.d.ts +14 -13
- package/lib/stores/webdaql/WebdaQLLexer.js +121 -112
- package/lib/stores/webdaql/WebdaQLLexer.js.map +1 -1
- package/lib/stores/webdaql/WebdaQLParserLexer.d.ts +14 -13
- package/lib/stores/webdaql/WebdaQLParserLexer.js +121 -112
- package/lib/stores/webdaql/WebdaQLParserLexer.js.map +1 -1
- package/lib/stores/webdaql/WebdaQLParserListener.d.ts +15 -3
- package/lib/stores/webdaql/WebdaQLParserParser.d.ts +23 -13
- package/lib/stores/webdaql/WebdaQLParserParser.js +149 -94
- package/lib/stores/webdaql/WebdaQLParserParser.js.map +1 -1
- package/lib/stores/webdaql/WebdaQLParserVisitor.d.ts +9 -2
- package/lib/stores/webdaql/query.d.ts +6 -2
- package/lib/stores/webdaql/query.js +14 -1
- package/lib/stores/webdaql/query.js.map +1 -1
- package/lib/stores/webdaql/query.spec.js +10 -1
- package/lib/stores/webdaql/query.spec.js.map +1 -1
- package/lib/test.d.ts +48 -19
- package/lib/test.js +171 -63
- package/lib/test.js.map +1 -1
- package/lib/unpackedapplication.d.ts +5 -0
- package/lib/unpackedapplication.js +58 -10
- package/lib/unpackedapplication.js.map +1 -1
- package/lib/utils/context.d.ts +76 -29
- package/lib/utils/context.js +91 -55
- package/lib/utils/context.js.map +1 -1
- package/lib/utils/context.spec.d.ts +9 -1
- package/lib/utils/context.spec.js +73 -8
- package/lib/utils/context.spec.js.map +1 -1
- package/lib/utils/cookie.d.ts +4 -5
- package/lib/utils/cookie.js +1 -2
- package/lib/utils/cookie.js.map +1 -1
- package/lib/utils/cookie.spec.js +5 -3
- package/lib/utils/cookie.spec.js.map +1 -1
- package/lib/utils/httpcontext.spec.js +9 -3
- package/lib/utils/httpcontext.spec.js.map +1 -1
- package/lib/utils/serializers.d.ts +46 -17
- package/lib/utils/serializers.js +116 -2
- package/lib/utils/serializers.js.map +1 -1
- package/lib/utils/serializers.spec.js +84 -20
- package/lib/utils/serializers.spec.js.map +1 -1
- package/lib/utils/session.d.ts +14 -8
- package/lib/utils/session.js +14 -3
- package/lib/utils/session.js.map +1 -1
- package/lib/utils/session.spec.js +6 -1
- package/lib/utils/session.spec.js.map +1 -1
- package/package.json +16 -10
- package/test/cachedapp/webda.config.json +6 -1
- package/test/config-cached.json +5 -0
- package/test/config-file-missing-file.json +5 -7
- package/test/config-file-no-reload.json +5 -7
- package/test/config-file-reload.json +5 -7
- package/test/config-kube-reload.json +5 -11
- package/test/config-reload.json +2 -4
- package/test/config.json +12 -2
- package/test/moddas/voidstore.js +1 -1
- package/test/models/ident.js +6 -4
- package/test/models/task.js +4 -4
- package/webda.module.json +1587 -1266
package/lib/models/coremodel.js
CHANGED
|
@@ -7,18 +7,98 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import util from "util";
|
|
8
8
|
import { v4 as uuidv4 } from "uuid";
|
|
9
9
|
import { Core } from "../core.js";
|
|
10
|
-
import {
|
|
10
|
+
import { WebdaError } from "../errors.js";
|
|
11
|
+
import { BinariesImpl, Binary } from "../services/binary.js";
|
|
12
|
+
import { Throttler } from "../utils/throttler.js";
|
|
13
|
+
import { createModelLinksMap, ModelLinksArray, ModelLinksSimpleArray, ModelMapLoaderImplementation } from "./relations.js";
|
|
11
14
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
15
|
+
* Expose the model through API or GraphQL if it exists
|
|
16
|
+
* The model will be exposed using its class name + 's'
|
|
17
|
+
* If you need to have a specific plural, use the annotation WebdaPlural
|
|
18
|
+
* to define the plural name
|
|
14
19
|
*
|
|
15
|
-
* @
|
|
20
|
+
* @returns
|
|
16
21
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
export function Expose(params = {}) {
|
|
23
|
+
return function (target) {
|
|
24
|
+
params.restrict ?? (params.restrict = {});
|
|
25
|
+
target.Expose = params;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
class CoreModelQuery {
|
|
32
|
+
constructor(type, model, attribute) {
|
|
33
|
+
this.attribute = attribute;
|
|
34
|
+
this.type = type;
|
|
35
|
+
this.model = model;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve target model definition
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
getTargetModel() {
|
|
42
|
+
this.targetModel ?? (this.targetModel = Core.get().getModel(this.type));
|
|
43
|
+
return this.targetModel;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Query the object
|
|
47
|
+
* @param query
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
query(query, context) {
|
|
51
|
+
return this.getTargetModel().query(this.completeQuery(query), true, context);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Complete the query with condition
|
|
55
|
+
* @param query
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
completeQuery(query) {
|
|
59
|
+
query = query ? `(${query}) AND` : "";
|
|
60
|
+
query += ` ${this.attribute} = '${this.model.getUuid()}'`;
|
|
61
|
+
return query;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @param callback
|
|
66
|
+
* @param context
|
|
67
|
+
*/
|
|
68
|
+
async forEach(callback, query, context, parallelism = 3) {
|
|
69
|
+
const throttler = new Throttler();
|
|
70
|
+
throttler.setConcurrency(parallelism);
|
|
71
|
+
let continuationToken;
|
|
72
|
+
do {
|
|
73
|
+
const result = await this.query(query + continuationToken ? "OFFSET " + continuationToken : "", context);
|
|
74
|
+
continuationToken = result.continuationToken;
|
|
75
|
+
for (const model of result.results) {
|
|
76
|
+
throttler.queue(() => callback(model));
|
|
77
|
+
}
|
|
78
|
+
await throttler.waitForCompletion();
|
|
79
|
+
} while (continuationToken);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get all objects linked
|
|
83
|
+
* @param context
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
async getAll(query, context) {
|
|
87
|
+
return Core.get().getModelStore(this.getTargetModel()).queryAll(this.completeQuery(query), context);
|
|
20
88
|
}
|
|
21
89
|
}
|
|
90
|
+
__decorate([
|
|
91
|
+
NotEnumerable
|
|
92
|
+
], CoreModelQuery.prototype, "type", void 0);
|
|
93
|
+
__decorate([
|
|
94
|
+
NotEnumerable
|
|
95
|
+
], CoreModelQuery.prototype, "model", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
NotEnumerable
|
|
98
|
+
], CoreModelQuery.prototype, "attribute", void 0);
|
|
99
|
+
__decorate([
|
|
100
|
+
NotEnumerable
|
|
101
|
+
], CoreModelQuery.prototype, "targetModel", void 0);
|
|
22
102
|
/**
|
|
23
103
|
* Make a property hidden from json
|
|
24
104
|
* @param target
|
|
@@ -59,6 +139,103 @@ export function Action(options = {}) {
|
|
|
59
139
|
};
|
|
60
140
|
};
|
|
61
141
|
}
|
|
142
|
+
export class ModelRef {
|
|
143
|
+
constructor(uuid, model) {
|
|
144
|
+
this.uuid = uuid;
|
|
145
|
+
this.model = model;
|
|
146
|
+
this.uuid = uuid === "" ? undefined : model.completeUid(uuid);
|
|
147
|
+
this.store = Core.get().getModelStore(model);
|
|
148
|
+
}
|
|
149
|
+
async get() {
|
|
150
|
+
return this.store.get(this.uuid);
|
|
151
|
+
}
|
|
152
|
+
set(id) {
|
|
153
|
+
this.uuid = id instanceof CoreModel ? id.getUuid() : id;
|
|
154
|
+
}
|
|
155
|
+
toString() {
|
|
156
|
+
return this.uuid;
|
|
157
|
+
}
|
|
158
|
+
toJSON() {
|
|
159
|
+
return this.uuid;
|
|
160
|
+
}
|
|
161
|
+
getUuid() {
|
|
162
|
+
return this.uuid;
|
|
163
|
+
}
|
|
164
|
+
deleteItemFromCollection(prop, index, itemWriteCondition, itemWriteConditionField) {
|
|
165
|
+
return this.store.deleteItemFromCollection(this.uuid, prop, index, itemWriteCondition, itemWriteConditionField);
|
|
166
|
+
}
|
|
167
|
+
upsertItemToCollection(prop, item, index, itemWriteCondition, itemWriteConditionField) {
|
|
168
|
+
return this.store.upsertItemToCollection(this.uuid, prop, item, index, itemWriteCondition, itemWriteConditionField);
|
|
169
|
+
}
|
|
170
|
+
exists() {
|
|
171
|
+
return this.store.exists(this.uuid);
|
|
172
|
+
}
|
|
173
|
+
delete() {
|
|
174
|
+
return this.store.delete(this.uuid);
|
|
175
|
+
}
|
|
176
|
+
conditionalPatch(updates, conditionField, condition) {
|
|
177
|
+
return this.store.conditionalPatch(this.uuid, updates, conditionField, condition);
|
|
178
|
+
}
|
|
179
|
+
patch(updates) {
|
|
180
|
+
return this.store.conditionalPatch(this.uuid, updates, null, undefined);
|
|
181
|
+
}
|
|
182
|
+
setAttribute(attribute, value) {
|
|
183
|
+
return this.store.setAttribute(this.uuid, attribute, value);
|
|
184
|
+
}
|
|
185
|
+
removeAttribute(attribute, itemWriteCondition, itemWriteConditionField) {
|
|
186
|
+
return this.store.removeAttribute(this.uuid, attribute, itemWriteCondition, itemWriteConditionField);
|
|
187
|
+
}
|
|
188
|
+
incrementAttributes(info) {
|
|
189
|
+
return this.store.incrementAttributes(this.uuid, info);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
__decorate([
|
|
193
|
+
NotEnumerable
|
|
194
|
+
], ModelRef.prototype, "store", void 0);
|
|
195
|
+
__decorate([
|
|
196
|
+
NotEnumerable
|
|
197
|
+
], ModelRef.prototype, "model", void 0);
|
|
198
|
+
export class ModelRefWithCreate extends ModelRef {
|
|
199
|
+
/**
|
|
200
|
+
* Allow to create a model
|
|
201
|
+
* @param defaultValue
|
|
202
|
+
* @param context
|
|
203
|
+
* @param withSave
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
async create(defaultValue, context, withSave = true) {
|
|
207
|
+
let result = new this.model().setContext(context).load(defaultValue, true).setUuid(this.uuid);
|
|
208
|
+
if (withSave) {
|
|
209
|
+
await result.save();
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Load a model from the known store
|
|
215
|
+
*
|
|
216
|
+
* @param this the class from which the static is called
|
|
217
|
+
* @param id of the object to load
|
|
218
|
+
* @param defaultValue if object not found return a default object
|
|
219
|
+
* @param context to set on the object
|
|
220
|
+
* @returns
|
|
221
|
+
*/
|
|
222
|
+
async getOrCreate(defaultValue, context, withSave = true) {
|
|
223
|
+
return (await this.get()) || this.create(defaultValue, context, withSave);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
export class ModelRefCustom extends ModelRef {
|
|
227
|
+
constructor(uuid, model, data) {
|
|
228
|
+
super(uuid, model);
|
|
229
|
+
this.uuid = uuid;
|
|
230
|
+
Object.assign(this, data);
|
|
231
|
+
}
|
|
232
|
+
toJSON() {
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
getUuid() {
|
|
236
|
+
return this.uuid;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
62
239
|
/**
|
|
63
240
|
* Basic Object in Webda
|
|
64
241
|
*
|
|
@@ -74,7 +251,18 @@ class CoreModel {
|
|
|
74
251
|
this.__dirty = new Set();
|
|
75
252
|
this.__class = new.target;
|
|
76
253
|
// Get the store automatically now
|
|
77
|
-
this.__store = Core.get()?.getModelStore(
|
|
254
|
+
this.__store = Core.get()?.getModelStore(new.target);
|
|
255
|
+
// Get the type automatically now
|
|
256
|
+
this.__type = process.env.WEBDA_V2_COMPATIBLE
|
|
257
|
+
? Core.get()?.getApplication().getModelFromInstance(this)
|
|
258
|
+
: Core.get()?.getApplication().getShortId(Core.get()?.getApplication().getModelFromInstance(this));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
*
|
|
262
|
+
* @returns
|
|
263
|
+
*/
|
|
264
|
+
static getRelations() {
|
|
265
|
+
return Core.get()?.getApplication().getRelations(this);
|
|
78
266
|
}
|
|
79
267
|
/**
|
|
80
268
|
* Get Store for this model
|
|
@@ -88,16 +276,72 @@ class CoreModel {
|
|
|
88
276
|
return Core.get().getModelStore(this);
|
|
89
277
|
}
|
|
90
278
|
/**
|
|
91
|
-
*
|
|
279
|
+
* Complete the uid with prefix if any
|
|
92
280
|
*
|
|
93
|
-
* Useful for
|
|
281
|
+
* Useful when object are stored with a prefix for full uuid
|
|
282
|
+
* @param uid
|
|
283
|
+
* @returns
|
|
284
|
+
*/
|
|
285
|
+
static completeUid(uid) {
|
|
286
|
+
return uid;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Return the known schema
|
|
290
|
+
* @returns
|
|
291
|
+
*/
|
|
292
|
+
static getSchema() {
|
|
293
|
+
const app = Core.get()?.getApplication();
|
|
294
|
+
return app?.getSchema(app.getModelFromConstructor(this));
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get a reference to a model
|
|
298
|
+
* @param this
|
|
299
|
+
* @param uid
|
|
300
|
+
* @returns
|
|
301
|
+
*/
|
|
302
|
+
static ref(uid) {
|
|
303
|
+
return new ModelRefWithCreate(uid, this);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Get a reference to a model
|
|
307
|
+
* @param this
|
|
308
|
+
* @param uid
|
|
309
|
+
* @returns
|
|
310
|
+
*/
|
|
311
|
+
static create(data) {
|
|
312
|
+
return new this().load(data, true).save();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Get identifier for this model
|
|
316
|
+
* @returns
|
|
317
|
+
*/
|
|
318
|
+
static getIdentifier(short = true) {
|
|
319
|
+
const res = Core.get().getApplication().getModelName(this);
|
|
320
|
+
if (short) {
|
|
321
|
+
return Core.get().getApplication().getShortId(res);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
return res;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Get the model hierarchy
|
|
94
329
|
*
|
|
330
|
+
* Ancestors will contain every model it inherits from
|
|
331
|
+
* Children will contain every model that inherits from this model in a tree structure
|
|
332
|
+
*/
|
|
333
|
+
static getHierarchy() {
|
|
334
|
+
return Core.get().getApplication().getModelHierarchy(this);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Unflat an object
|
|
338
|
+
* @param data
|
|
95
339
|
* @param split
|
|
96
340
|
* @returns
|
|
97
341
|
*/
|
|
98
|
-
unflat(split = "#") {
|
|
342
|
+
static unflat(data, split = "#") {
|
|
99
343
|
const res = {};
|
|
100
|
-
for (let i in
|
|
344
|
+
for (let i in data) {
|
|
101
345
|
const attrs = i.split(split);
|
|
102
346
|
let attr = attrs.shift();
|
|
103
347
|
let cur = res;
|
|
@@ -107,22 +351,78 @@ class CoreModel {
|
|
|
107
351
|
cur = cur[attr];
|
|
108
352
|
}
|
|
109
353
|
else {
|
|
110
|
-
cur[attr] =
|
|
354
|
+
cur[attr] = data[i];
|
|
111
355
|
}
|
|
112
356
|
attr = attrs.shift();
|
|
113
357
|
}
|
|
114
358
|
}
|
|
115
359
|
return res;
|
|
116
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Create subobject for a model
|
|
363
|
+
*
|
|
364
|
+
* Useful for counters
|
|
365
|
+
*
|
|
366
|
+
* @param split
|
|
367
|
+
* @returns
|
|
368
|
+
*/
|
|
369
|
+
unflat(split = "#") {
|
|
370
|
+
return CoreModel.unflat(this, split);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Flat an object into another
|
|
374
|
+
*
|
|
375
|
+
* {
|
|
376
|
+
* a: {
|
|
377
|
+
* b: 1
|
|
378
|
+
* },
|
|
379
|
+
* c: 1
|
|
380
|
+
* }
|
|
381
|
+
*
|
|
382
|
+
* become
|
|
383
|
+
*
|
|
384
|
+
* {
|
|
385
|
+
* "a#b": 1
|
|
386
|
+
* "c": 1
|
|
387
|
+
* }
|
|
388
|
+
*
|
|
389
|
+
* @param target
|
|
390
|
+
* @param data
|
|
391
|
+
* @param split
|
|
392
|
+
* @param prefix
|
|
393
|
+
*/
|
|
394
|
+
static flat(target, data, split = "#", prefix = "") {
|
|
395
|
+
for (let i in data) {
|
|
396
|
+
if (typeof data[i] === "object") {
|
|
397
|
+
CoreModel.flat(target, data[i], split, i + split);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
target[prefix + i] = data[i];
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
117
404
|
/**
|
|
118
405
|
* Query for models
|
|
119
406
|
* @param this
|
|
120
407
|
* @param id
|
|
121
408
|
* @returns
|
|
122
409
|
*/
|
|
123
|
-
static async query(query) {
|
|
410
|
+
static async query(query = "", includeSubclass = true, context) {
|
|
411
|
+
if (!query.includes("__type")) {
|
|
412
|
+
if (query.trim() !== "") {
|
|
413
|
+
query = ` AND ${query}`;
|
|
414
|
+
}
|
|
415
|
+
const app = Core.get().getApplication();
|
|
416
|
+
const name = app.getShortId(app.getModelName(this));
|
|
417
|
+
if (includeSubclass) {
|
|
418
|
+
query = `__types CONTAINS "${name}"${query}`;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
query = `__type = "${name}"${query}`;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
124
424
|
// @ts-ignore
|
|
125
|
-
return this.store().query(query);
|
|
425
|
+
return this.store().query(query, context);
|
|
126
426
|
}
|
|
127
427
|
/**
|
|
128
428
|
* Return a proxy to the object to detect if dirty
|
|
@@ -137,7 +437,7 @@ class CoreModel {
|
|
|
137
437
|
return true;
|
|
138
438
|
},
|
|
139
439
|
get: (target, p) => {
|
|
140
|
-
if (Array.isArray(target[p]) ||
|
|
440
|
+
if (Array.isArray(target[p]) || target[p] instanceof Object) {
|
|
141
441
|
return new Proxy(target[p], subProxier(prop));
|
|
142
442
|
}
|
|
143
443
|
return target[p];
|
|
@@ -166,8 +466,7 @@ class CoreModel {
|
|
|
166
466
|
if (typeof p === "string" && p.startsWith("__")) {
|
|
167
467
|
return target[p];
|
|
168
468
|
}
|
|
169
|
-
if (Array.isArray(target[p]) ||
|
|
170
|
-
(typeof target[p] === "object" && target[p].constructor.prototype === Object.prototype)) {
|
|
469
|
+
if (Array.isArray(target[p]) || target[p] instanceof Object) {
|
|
171
470
|
return new Proxy(target[p], subProxier(p));
|
|
172
471
|
}
|
|
173
472
|
return target[p];
|
|
@@ -226,12 +525,18 @@ class CoreModel {
|
|
|
226
525
|
static getPermissionQuery(_ctx) {
|
|
227
526
|
return null;
|
|
228
527
|
}
|
|
528
|
+
async checkAct(context, action) {
|
|
529
|
+
let msg = await this.canAct(context, action);
|
|
530
|
+
if (msg !== true) {
|
|
531
|
+
throw new WebdaError.Forbidden(msg === false ? "No permission" : msg);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
229
534
|
/**
|
|
230
535
|
* By default nothing is permitted on a CoreModel
|
|
231
536
|
* @returns
|
|
232
537
|
*/
|
|
233
|
-
async canAct(
|
|
234
|
-
|
|
538
|
+
async canAct(_context, _action) {
|
|
539
|
+
return "This model does not support any action: override checkAct";
|
|
235
540
|
}
|
|
236
541
|
/**
|
|
237
542
|
* Get the UUID property
|
|
@@ -239,18 +544,6 @@ class CoreModel {
|
|
|
239
544
|
static getUuidField() {
|
|
240
545
|
return "uuid";
|
|
241
546
|
}
|
|
242
|
-
/**
|
|
243
|
-
* Get the UUID property
|
|
244
|
-
*/
|
|
245
|
-
static getLastUpdateField() {
|
|
246
|
-
return "_lastUpdate";
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Get the UUID property
|
|
250
|
-
*/
|
|
251
|
-
static getCreationField() {
|
|
252
|
-
return "_creationDate";
|
|
253
|
-
}
|
|
254
547
|
/**
|
|
255
548
|
* Create an object
|
|
256
549
|
* @returns
|
|
@@ -266,21 +559,6 @@ class CoreModel {
|
|
|
266
559
|
static instanceOf(object) {
|
|
267
560
|
return (typeof object.toStoredJSON === "function" && object.__class && object.__class.factory && object.__class.instanceOf);
|
|
268
561
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Return if an object is attached to its store
|
|
271
|
-
* @deprecated Will be removed in 3.0
|
|
272
|
-
*/
|
|
273
|
-
isAttached() {
|
|
274
|
-
return this.__store !== undefined;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Attach an object to a store instance
|
|
278
|
-
* @deprecated Will be removed in 3.0
|
|
279
|
-
*/
|
|
280
|
-
attach(store) {
|
|
281
|
-
this.__store = store;
|
|
282
|
-
return this;
|
|
283
|
-
}
|
|
284
562
|
/**
|
|
285
563
|
* Return a unique reference within the application to the object
|
|
286
564
|
*
|
|
@@ -288,10 +566,7 @@ class CoreModel {
|
|
|
288
566
|
* @returns
|
|
289
567
|
*/
|
|
290
568
|
getFullUuid() {
|
|
291
|
-
|
|
292
|
-
throw new Error("Cannot return full uuid of unattached object");
|
|
293
|
-
}
|
|
294
|
-
return `${this.__store.getName()}$${this.getUuid()}`;
|
|
569
|
+
return `${this.__type.replace(/\//, "-")}$${this.getUuid()}`;
|
|
295
570
|
}
|
|
296
571
|
/**
|
|
297
572
|
* Get an object from the full uuid
|
|
@@ -300,27 +575,13 @@ class CoreModel {
|
|
|
300
575
|
* @param partials
|
|
301
576
|
* @returns
|
|
302
577
|
*/
|
|
303
|
-
static async fromFullUuid(
|
|
304
|
-
const [
|
|
305
|
-
let
|
|
578
|
+
static async fromFullUuid(fullUuid, core = Core.get(), partials) {
|
|
579
|
+
const [model, uuid] = fullUuid.split("$");
|
|
580
|
+
let modelObject = core.getApplication().getModel(model.replace("-", "/"));
|
|
306
581
|
if (partials) {
|
|
307
|
-
return
|
|
308
|
-
}
|
|
309
|
-
return service.get(uuid);
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Remove all the attribute starting with __
|
|
313
|
-
* @param key
|
|
314
|
-
* @param value
|
|
315
|
-
* @returns
|
|
316
|
-
*
|
|
317
|
-
* @deprecated
|
|
318
|
-
*/
|
|
319
|
-
_jsonFilter(key, value) {
|
|
320
|
-
if (key[0] === "_" && key.length > 1 && key[1] === "_") {
|
|
321
|
-
return undefined;
|
|
582
|
+
return new modelObject().load(partials, true).setUuid(uuid);
|
|
322
583
|
}
|
|
323
|
-
return
|
|
584
|
+
return new modelObject().setUuid(uuid).get();
|
|
324
585
|
}
|
|
325
586
|
/**
|
|
326
587
|
* Allow to define custom permission per attribute
|
|
@@ -339,8 +600,7 @@ class CoreModel {
|
|
|
339
600
|
return key.startsWith("_") ? undefined : value;
|
|
340
601
|
}
|
|
341
602
|
else {
|
|
342
|
-
|
|
343
|
-
return this._jsonFilter(key, value);
|
|
603
|
+
return !key.startsWith("__") ? value : undefined;
|
|
344
604
|
}
|
|
345
605
|
}
|
|
346
606
|
/**
|
|
@@ -359,6 +619,7 @@ class CoreModel {
|
|
|
359
619
|
continue;
|
|
360
620
|
}
|
|
361
621
|
}
|
|
622
|
+
// @ts-ignore
|
|
362
623
|
this[prop] = val;
|
|
363
624
|
}
|
|
364
625
|
if (this._creationDate) {
|
|
@@ -370,8 +631,57 @@ class CoreModel {
|
|
|
370
631
|
if (!this.getUuid()) {
|
|
371
632
|
this.setUuid(this.generateUid(raw));
|
|
372
633
|
}
|
|
634
|
+
this.handleRelations();
|
|
373
635
|
return this;
|
|
374
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* Patch every attribute that is based on a relation
|
|
639
|
+
* to add all the helpers
|
|
640
|
+
*/
|
|
641
|
+
handleRelations() {
|
|
642
|
+
var _a, _b;
|
|
643
|
+
const rel = Core.get()
|
|
644
|
+
?.getApplication()
|
|
645
|
+
?.getRelations(this) || {};
|
|
646
|
+
for (let link of rel.links || []) {
|
|
647
|
+
const model = Core.get().getModel(link.model);
|
|
648
|
+
if (link.type === "LINK") {
|
|
649
|
+
this[_a = link.attribute] ?? (this[_a] = "");
|
|
650
|
+
if (typeof this[link.attribute] === "string") {
|
|
651
|
+
this[link.attribute] = new ModelRef(this[link.attribute], model);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
else if (link.type === "LINKS_ARRAY") {
|
|
655
|
+
this[link.attribute] = new ModelLinksArray(model, this[link.attribute]);
|
|
656
|
+
}
|
|
657
|
+
else if (link.type === "LINKS_SIMPLE_ARRAY") {
|
|
658
|
+
this[link.attribute] = new ModelLinksSimpleArray(model, this[link.attribute]);
|
|
659
|
+
}
|
|
660
|
+
else if (link.type === "LINKS_MAP") {
|
|
661
|
+
this[link.attribute] = createModelLinksMap(model, this[link.attribute]);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
for (let link of rel.maps || []) {
|
|
665
|
+
this[link.attribute] = (this[link.attribute] || []).map(el => new ModelMapLoaderImplementation(Core.get().getModel(link.model), el));
|
|
666
|
+
}
|
|
667
|
+
for (let query of rel.queries || []) {
|
|
668
|
+
this[query.attribute] = new CoreModelQuery(query.model, this, query.targetAttribute);
|
|
669
|
+
}
|
|
670
|
+
if (rel.parent) {
|
|
671
|
+
this[_b = rel.parent.attribute] ?? (this[_b] = "");
|
|
672
|
+
if (typeof this[rel.parent.attribute] === "string") {
|
|
673
|
+
this[rel.parent.attribute] = new ModelRef(this[rel.parent.attribute], Core.get().getModel(rel.parent.model));
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
for (let binary of rel.binaries || []) {
|
|
677
|
+
if (binary.cardinality === "ONE") {
|
|
678
|
+
this[binary.attribute] = new Binary(binary.attribute, this);
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
this[binary.attribute] = new BinariesImpl().assign(this, binary.attribute);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
375
685
|
/**
|
|
376
686
|
* Context of the request
|
|
377
687
|
*/
|
|
@@ -385,7 +695,7 @@ class CoreModel {
|
|
|
385
695
|
* Global object does not belong to a request
|
|
386
696
|
*/
|
|
387
697
|
getContext() {
|
|
388
|
-
return this.__ctx ||
|
|
698
|
+
return this.__ctx || Core.get().getGlobalContext();
|
|
389
699
|
}
|
|
390
700
|
/**
|
|
391
701
|
* Return the object registered store
|
|
@@ -406,9 +716,6 @@ class CoreModel {
|
|
|
406
716
|
* @throws Error if the object is not coming from a store
|
|
407
717
|
*/
|
|
408
718
|
async refresh() {
|
|
409
|
-
if (!this.__store) {
|
|
410
|
-
throw new CoreModelUnattachedError();
|
|
411
|
-
}
|
|
412
719
|
let obj = await this.__store.get(this.getUuid());
|
|
413
720
|
if (obj) {
|
|
414
721
|
Object.assign(this, obj);
|
|
@@ -418,6 +725,7 @@ class CoreModel {
|
|
|
418
725
|
delete this[i];
|
|
419
726
|
}
|
|
420
727
|
}
|
|
728
|
+
this.handleRelations();
|
|
421
729
|
}
|
|
422
730
|
return this;
|
|
423
731
|
}
|
|
@@ -427,24 +735,8 @@ class CoreModel {
|
|
|
427
735
|
* @throws Error if the object is not coming from a store
|
|
428
736
|
*/
|
|
429
737
|
async delete() {
|
|
430
|
-
if (!this.__store) {
|
|
431
|
-
throw new CoreModelUnattachedError();
|
|
432
|
-
}
|
|
433
738
|
return this.__store.delete(this.getUuid());
|
|
434
739
|
}
|
|
435
|
-
/**
|
|
436
|
-
* Load a model from the known store
|
|
437
|
-
*
|
|
438
|
-
* @param this the class from which the static is called
|
|
439
|
-
* @param id of the object to load
|
|
440
|
-
* @param defaultValue if object not found return a default object
|
|
441
|
-
* @param context to set on the object
|
|
442
|
-
* @returns
|
|
443
|
-
*/
|
|
444
|
-
static async get(id, defaultValue, context) {
|
|
445
|
-
// @ts-ignore
|
|
446
|
-
return this.store(this).get(id, context, defaultValue);
|
|
447
|
-
}
|
|
448
740
|
/**
|
|
449
741
|
* Patch current object with this update
|
|
450
742
|
* @param obj
|
|
@@ -452,9 +744,6 @@ class CoreModel {
|
|
|
452
744
|
* @param conditionValue
|
|
453
745
|
*/
|
|
454
746
|
async patch(obj, conditionField, conditionValue) {
|
|
455
|
-
if (!this.__store) {
|
|
456
|
-
throw new CoreModelUnattachedError();
|
|
457
|
-
}
|
|
458
747
|
await this.__store.patch({ [this.__class.getUuidField()]: this.getUuid(), ...obj }, true, conditionField, conditionValue);
|
|
459
748
|
Object.assign(this, obj);
|
|
460
749
|
}
|
|
@@ -464,9 +753,6 @@ class CoreModel {
|
|
|
464
753
|
* @throws Error if the object is not coming from a store
|
|
465
754
|
*/
|
|
466
755
|
async save(full, ...args) {
|
|
467
|
-
if (!this.__store) {
|
|
468
|
-
throw new CoreModelUnattachedError();
|
|
469
|
-
}
|
|
470
756
|
// If proxy is not used and not field specified call save
|
|
471
757
|
if ((!util.types.isProxy(this) && full === undefined) || full === true) {
|
|
472
758
|
if (!this._creationDate || !this._lastUpdate) {
|
|
@@ -533,9 +819,6 @@ class CoreModel {
|
|
|
533
819
|
* WARNING: Only object attached to a store can retrieve service
|
|
534
820
|
*/
|
|
535
821
|
getService(service) {
|
|
536
|
-
if (!this.__store) {
|
|
537
|
-
throw new CoreModelUnattachedError();
|
|
538
|
-
}
|
|
539
822
|
return this.__store.getService(service);
|
|
540
823
|
}
|
|
541
824
|
/**
|
|
@@ -555,7 +838,12 @@ class CoreModel {
|
|
|
555
838
|
}
|
|
556
839
|
if (value === undefined)
|
|
557
840
|
continue;
|
|
558
|
-
|
|
841
|
+
if (value instanceof ModelRef) {
|
|
842
|
+
obj[i] = value.toString();
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
obj[i] = value;
|
|
846
|
+
}
|
|
559
847
|
}
|
|
560
848
|
return obj;
|
|
561
849
|
}
|
|
@@ -624,5 +912,17 @@ __decorate([
|
|
|
624
912
|
__decorate([
|
|
625
913
|
NotEnumerable
|
|
626
914
|
], CoreModel.prototype, "__dirty", void 0);
|
|
627
|
-
|
|
915
|
+
/**
|
|
916
|
+
* CoreModel with a uuid
|
|
917
|
+
*/
|
|
918
|
+
class UuidModel extends CoreModel {
|
|
919
|
+
/**
|
|
920
|
+
* @override
|
|
921
|
+
*/
|
|
922
|
+
validate(ctx, updates, ignoreRequired) {
|
|
923
|
+
updates.uuid ?? (updates.uuid = this.generateUid());
|
|
924
|
+
return super.validate(ctx, updates, ignoreRequired);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
export { CoreModel, UuidModel };
|
|
628
928
|
//# sourceMappingURL=coremodel.js.map
|