@webda/core 2.4.2 → 3.0.1

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.
Files changed (227) hide show
  1. package/lib/application.d.ts +171 -34
  2. package/lib/application.js +243 -47
  3. package/lib/application.js.map +1 -1
  4. package/lib/application.spec.js +44 -8
  5. package/lib/application.spec.js.map +1 -1
  6. package/lib/core.d.ts +113 -54
  7. package/lib/core.js +222 -135
  8. package/lib/core.js.map +1 -1
  9. package/lib/core.spec.js +87 -43
  10. package/lib/core.spec.js.map +1 -1
  11. package/lib/errors.d.ts +65 -0
  12. package/lib/errors.js +113 -0
  13. package/lib/errors.js.map +1 -0
  14. package/lib/errors.spec.d.ts +1 -0
  15. package/lib/errors.spec.js +33 -0
  16. package/lib/errors.spec.js.map +1 -0
  17. package/lib/index.d.ts +3 -0
  18. package/lib/index.js +3 -0
  19. package/lib/index.js.map +1 -1
  20. package/lib/models/aclmodel.d.ts +4 -4
  21. package/lib/models/aclmodel.js +10 -6
  22. package/lib/models/aclmodel.js.map +1 -1
  23. package/lib/models/aclmodel.spec.js +33 -24
  24. package/lib/models/aclmodel.spec.js.map +1 -1
  25. package/lib/models/coremodel.d.ts +284 -92
  26. package/lib/models/coremodel.js +403 -103
  27. package/lib/models/coremodel.js.map +1 -1
  28. package/lib/models/coremodel.spec.js +162 -24
  29. package/lib/models/coremodel.spec.js.map +1 -1
  30. package/lib/models/ident.d.ts +20 -6
  31. package/lib/models/ident.js.map +1 -1
  32. package/lib/models/ownermodel.d.ts +13 -23
  33. package/lib/models/ownermodel.js +24 -51
  34. package/lib/models/ownermodel.js.map +1 -1
  35. package/lib/models/ownermodel.spec.js +23 -11
  36. package/lib/models/ownermodel.spec.js.map +1 -1
  37. package/lib/models/relations.d.ts +167 -0
  38. package/lib/models/relations.js +113 -0
  39. package/lib/models/relations.js.map +1 -0
  40. package/lib/models/rolemodel.d.ts +3 -3
  41. package/lib/models/rolemodel.js +6 -6
  42. package/lib/models/rolemodel.js.map +1 -1
  43. package/lib/models/rolemodel.spec.js +12 -12
  44. package/lib/models/rolemodel.spec.js.map +1 -1
  45. package/lib/models/user.d.ts +40 -24
  46. package/lib/models/user.js +74 -48
  47. package/lib/models/user.js.map +1 -1
  48. package/lib/models/user.spec.js +24 -4
  49. package/lib/models/user.spec.js.map +1 -1
  50. package/lib/queues/memoryqueue.spec.js +9 -5
  51. package/lib/queues/memoryqueue.spec.js.map +1 -1
  52. package/lib/queues/queueservice.js.map +1 -1
  53. package/lib/router.d.ts +17 -8
  54. package/lib/router.js +81 -9
  55. package/lib/router.js.map +1 -1
  56. package/lib/router.spec.js +89 -5
  57. package/lib/router.spec.js.map +1 -1
  58. package/lib/services/asyncevents.spec.js +4 -4
  59. package/lib/services/authentication.d.ts +21 -22
  60. package/lib/services/authentication.js +90 -109
  61. package/lib/services/authentication.js.map +1 -1
  62. package/lib/services/authentication.spec.js +51 -65
  63. package/lib/services/authentication.spec.js.map +1 -1
  64. package/lib/services/binary.d.ts +132 -31
  65. package/lib/services/binary.js +257 -72
  66. package/lib/services/binary.js.map +1 -1
  67. package/lib/services/binary.spec.d.ts +16 -6
  68. package/lib/services/binary.spec.js +44 -117
  69. package/lib/services/binary.spec.js.map +1 -1
  70. package/lib/services/cloudbinary.d.ts +9 -10
  71. package/lib/services/cloudbinary.js +14 -15
  72. package/lib/services/cloudbinary.js.map +1 -1
  73. package/lib/services/cloudbinary.spec.d.ts +2 -2
  74. package/lib/services/cloudbinary.spec.js +13 -12
  75. package/lib/services/cloudbinary.spec.js.map +1 -1
  76. package/lib/services/configuration.js +9 -9
  77. package/lib/services/configuration.js.map +1 -1
  78. package/lib/services/configuration.spec.js +5 -7
  79. package/lib/services/configuration.spec.js.map +1 -1
  80. package/lib/services/cron.spec.js +3 -4
  81. package/lib/services/cron.spec.js.map +1 -1
  82. package/lib/services/cryptoservice.d.ts +2 -2
  83. package/lib/services/cryptoservice.js +5 -2
  84. package/lib/services/cryptoservice.js.map +1 -1
  85. package/lib/services/domainservice.d.ts +113 -0
  86. package/lib/services/domainservice.js +357 -0
  87. package/lib/services/domainservice.js.map +1 -0
  88. package/lib/services/domainservice.spec.d.ts +1 -0
  89. package/lib/services/domainservice.spec.js +334 -0
  90. package/lib/services/domainservice.spec.js.map +1 -0
  91. package/lib/services/echo.d.ts +2 -2
  92. package/lib/services/echo.js.map +1 -1
  93. package/lib/services/echo.spec.js +9 -2
  94. package/lib/services/echo.spec.js.map +1 -1
  95. package/lib/services/filebinary.d.ts +13 -14
  96. package/lib/services/filebinary.js +79 -73
  97. package/lib/services/filebinary.js.map +1 -1
  98. package/lib/services/filebinary.spec.d.ts +5 -0
  99. package/lib/services/filebinary.spec.js +222 -11
  100. package/lib/services/filebinary.spec.js.map +1 -1
  101. package/lib/services/fileconfiguration.js +4 -4
  102. package/lib/services/fileconfiguration.js.map +1 -1
  103. package/lib/services/fileconfiguration.spec.js +23 -24
  104. package/lib/services/fileconfiguration.spec.js.map +1 -1
  105. package/lib/services/invitationservice.d.ts +11 -9
  106. package/lib/services/invitationservice.js +17 -23
  107. package/lib/services/invitationservice.js.map +1 -1
  108. package/lib/services/invitationservice.spec.js +43 -40
  109. package/lib/services/invitationservice.spec.js.map +1 -1
  110. package/lib/services/kubernetesconfiguration.js +12 -22
  111. package/lib/services/kubernetesconfiguration.js.map +1 -1
  112. package/lib/services/kubernetesconfiguration.spec.js +1 -6
  113. package/lib/services/kubernetesconfiguration.spec.js.map +1 -1
  114. package/lib/services/mailer.js +1 -1
  115. package/lib/services/mailer.js.map +1 -1
  116. package/lib/services/mailer.spec.js +4 -1
  117. package/lib/services/mailer.spec.js.map +1 -1
  118. package/lib/services/oauth.d.ts +17 -9
  119. package/lib/services/oauth.js +30 -4
  120. package/lib/services/oauth.js.map +1 -1
  121. package/lib/services/oauth.spec.js +32 -15
  122. package/lib/services/oauth.spec.js.map +1 -1
  123. package/lib/services/prometheus.spec.js.map +1 -1
  124. package/lib/services/proxy.d.ts +9 -8
  125. package/lib/services/proxy.js +65 -36
  126. package/lib/services/proxy.js.map +1 -1
  127. package/lib/services/proxy.spec.js +28 -2
  128. package/lib/services/proxy.spec.js.map +1 -1
  129. package/lib/services/resource.d.ts +3 -3
  130. package/lib/services/resource.js +4 -3
  131. package/lib/services/resource.js.map +1 -1
  132. package/lib/services/resource.spec.js +3 -3
  133. package/lib/services/resource.spec.js.map +1 -1
  134. package/lib/services/service.d.ts +10 -13
  135. package/lib/services/service.js +29 -13
  136. package/lib/services/service.js.map +1 -1
  137. package/lib/services/service.spec.js +49 -11
  138. package/lib/services/service.spec.js.map +1 -1
  139. package/lib/services/version.d.ts +2 -2
  140. package/lib/services/version.js.map +1 -1
  141. package/lib/stores/aggregator.js +1 -0
  142. package/lib/stores/aggregator.js.map +1 -1
  143. package/lib/stores/aliasstore.d.ts +2 -2
  144. package/lib/stores/aliasstore.js +15 -4
  145. package/lib/stores/aliasstore.js.map +1 -1
  146. package/lib/stores/aliasstore.spec.js +4 -2
  147. package/lib/stores/aliasstore.spec.js.map +1 -1
  148. package/lib/stores/file.d.ts +5 -2
  149. package/lib/stores/file.js +11 -8
  150. package/lib/stores/file.js.map +1 -1
  151. package/lib/stores/file.spec.js +21 -34
  152. package/lib/stores/file.spec.js.map +1 -1
  153. package/lib/stores/mapper.d.ts +4 -2
  154. package/lib/stores/mapper.js +18 -11
  155. package/lib/stores/mapper.js.map +1 -1
  156. package/lib/stores/mapper.spec.js +6 -3
  157. package/lib/stores/mapper.spec.js.map +1 -1
  158. package/lib/stores/memory.d.ts +5 -2
  159. package/lib/stores/memory.js +11 -9
  160. package/lib/stores/memory.js.map +1 -1
  161. package/lib/stores/memory.spec.d.ts +3 -0
  162. package/lib/stores/memory.spec.js +100 -11
  163. package/lib/stores/memory.spec.js.map +1 -1
  164. package/lib/stores/store.d.ts +177 -87
  165. package/lib/stores/store.js +312 -141
  166. package/lib/stores/store.js.map +1 -1
  167. package/lib/stores/store.spec.d.ts +2 -2
  168. package/lib/stores/store.spec.js +54 -38
  169. package/lib/stores/store.spec.js.map +1 -1
  170. package/lib/stores/webdaql/WebdaQLLexer.d.ts +14 -13
  171. package/lib/stores/webdaql/WebdaQLLexer.js +121 -112
  172. package/lib/stores/webdaql/WebdaQLLexer.js.map +1 -1
  173. package/lib/stores/webdaql/WebdaQLParserLexer.d.ts +14 -13
  174. package/lib/stores/webdaql/WebdaQLParserLexer.js +121 -112
  175. package/lib/stores/webdaql/WebdaQLParserLexer.js.map +1 -1
  176. package/lib/stores/webdaql/WebdaQLParserListener.d.ts +15 -3
  177. package/lib/stores/webdaql/WebdaQLParserParser.d.ts +23 -13
  178. package/lib/stores/webdaql/WebdaQLParserParser.js +149 -94
  179. package/lib/stores/webdaql/WebdaQLParserParser.js.map +1 -1
  180. package/lib/stores/webdaql/WebdaQLParserVisitor.d.ts +9 -2
  181. package/lib/stores/webdaql/query.d.ts +6 -2
  182. package/lib/stores/webdaql/query.js +14 -1
  183. package/lib/stores/webdaql/query.js.map +1 -1
  184. package/lib/stores/webdaql/query.spec.js +10 -1
  185. package/lib/stores/webdaql/query.spec.js.map +1 -1
  186. package/lib/test.d.ts +48 -19
  187. package/lib/test.js +171 -63
  188. package/lib/test.js.map +1 -1
  189. package/lib/unpackedapplication.d.ts +5 -0
  190. package/lib/unpackedapplication.js +58 -10
  191. package/lib/unpackedapplication.js.map +1 -1
  192. package/lib/utils/context.d.ts +76 -29
  193. package/lib/utils/context.js +91 -55
  194. package/lib/utils/context.js.map +1 -1
  195. package/lib/utils/context.spec.d.ts +9 -1
  196. package/lib/utils/context.spec.js +73 -8
  197. package/lib/utils/context.spec.js.map +1 -1
  198. package/lib/utils/cookie.d.ts +4 -5
  199. package/lib/utils/cookie.js +1 -2
  200. package/lib/utils/cookie.js.map +1 -1
  201. package/lib/utils/cookie.spec.js +5 -3
  202. package/lib/utils/cookie.spec.js.map +1 -1
  203. package/lib/utils/httpcontext.spec.js +9 -3
  204. package/lib/utils/httpcontext.spec.js.map +1 -1
  205. package/lib/utils/serializers.d.ts +46 -17
  206. package/lib/utils/serializers.js +116 -2
  207. package/lib/utils/serializers.js.map +1 -1
  208. package/lib/utils/serializers.spec.js +84 -20
  209. package/lib/utils/serializers.spec.js.map +1 -1
  210. package/lib/utils/session.d.ts +14 -8
  211. package/lib/utils/session.js +14 -3
  212. package/lib/utils/session.js.map +1 -1
  213. package/lib/utils/session.spec.js +6 -1
  214. package/lib/utils/session.spec.js.map +1 -1
  215. package/package.json +16 -10
  216. package/test/cachedapp/webda.config.json +6 -1
  217. package/test/config-cached.json +5 -0
  218. package/test/config-file-missing-file.json +5 -7
  219. package/test/config-file-no-reload.json +5 -7
  220. package/test/config-file-reload.json +5 -7
  221. package/test/config-kube-reload.json +5 -11
  222. package/test/config-reload.json +2 -4
  223. package/test/config.json +12 -2
  224. package/test/moddas/voidstore.js +1 -1
  225. package/test/models/ident.js +6 -4
  226. package/test/models/task.js +4 -4
  227. package/webda.module.json +1587 -1266
@@ -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 { Context } from "../utils/context.js";
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
- * Sent if action required attached CoreModel is trigger
13
- * A Model cannot be detached anymore
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
- * @deprecated
20
+ * @returns
16
21
  */
17
- export class CoreModelUnattachedError extends Error {
18
- constructor() {
19
- super("No store linked to this object");
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(this);
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
- * Create subobject for a model
279
+ * Complete the uid with prefix if any
92
280
  *
93
- * Useful for counters
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 this) {
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] = this[i];
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]) || (target[p] instanceof Object && target[p].prototype == Object.prototype)) {
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(_ctx, _action) {
234
- throw 403;
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
- if (!this.isAttached()) {
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(core, fullUuid, partials) {
304
- const [store, uuid] = fullUuid.split("$");
305
- let service = core.getService(store);
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 service.newModel(partials).setUuid(uuid);
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 value;
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
- // Will be replaced by this !key.startsWith("__") in 3.0.0
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 || Context.getGlobalContext();
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
- obj[i] = value;
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
- export { CoreModel };
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