@rws-framework/db 2.3.2 → 2.4.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.
Files changed (92) hide show
  1. package/.bin/add-v.sh +9 -9
  2. package/.bin/emerge.sh +10 -10
  3. package/.eslintrc.json +53 -53
  4. package/README.md +404 -367
  5. package/dist/decorators/InverseRelation.d.ts +12 -12
  6. package/dist/decorators/InverseRelation.js +24 -24
  7. package/dist/decorators/InverseTimeSeries.d.ts +8 -8
  8. package/dist/decorators/InverseTimeSeries.js +13 -13
  9. package/dist/decorators/RWSCollection.d.ts +12 -12
  10. package/dist/decorators/RWSCollection.js +16 -16
  11. package/dist/decorators/Relation.d.ts +19 -19
  12. package/dist/decorators/Relation.js +26 -26
  13. package/dist/decorators/TrackType.d.ts +20 -20
  14. package/dist/decorators/TrackType.js +41 -41
  15. package/dist/decorators/index.d.ts +5 -5
  16. package/dist/decorators/index.js +14 -14
  17. package/dist/helper/DbHelper.d.ts +8 -8
  18. package/dist/helper/DbHelper.js +141 -141
  19. package/dist/helper/FieldsHelper.d.ts +4 -4
  20. package/dist/helper/FieldsHelper.js +35 -35
  21. package/dist/index.d.ts +12 -12
  22. package/dist/index.js +19 -19
  23. package/dist/models/TimeSeriesModel.d.ts +7 -7
  24. package/dist/models/TimeSeriesModel.js +33 -33
  25. package/dist/models/_model.d.ts +6 -6
  26. package/dist/models/_model.js +9 -9
  27. package/dist/models/core/RWSModel.d.ts +66 -66
  28. package/dist/models/core/RWSModel.js +400 -400
  29. package/dist/models/core/TimeSeriesModel.d.ts +1 -1
  30. package/dist/models/core/TimeSeriesModel.js +14 -14
  31. package/dist/models/index.d.ts +7 -7
  32. package/dist/models/index.js +8 -8
  33. package/dist/models/interfaces/IModel.d.ts +11 -11
  34. package/dist/models/interfaces/IModel.js +2 -2
  35. package/dist/models/interfaces/IRWSModelServices.d.ts +6 -6
  36. package/dist/models/interfaces/IRWSModelServices.js +2 -2
  37. package/dist/models/interfaces/OpModelType.d.ts +31 -31
  38. package/dist/models/interfaces/OpModelType.js +2 -2
  39. package/dist/models/types/RelationTypes.d.ts +24 -24
  40. package/dist/models/types/RelationTypes.js +2 -2
  41. package/dist/models/utils/ModelUtils.d.ts +10 -10
  42. package/dist/models/utils/ModelUtils.js +56 -56
  43. package/dist/models/utils/PaginationUtils.d.ts +5 -5
  44. package/dist/models/utils/PaginationUtils.js +32 -32
  45. package/dist/models/utils/RelationUtils.d.ts +14 -14
  46. package/dist/models/utils/RelationUtils.js +65 -65
  47. package/dist/models/utils/TimeSeriesUtils.d.ts +11 -11
  48. package/dist/models/utils/TimeSeriesUtils.js +35 -35
  49. package/dist/services/DBService.d.ts +37 -37
  50. package/dist/services/DBService.js +198 -198
  51. package/dist/types/DbConfigHandler.d.ts +9 -9
  52. package/dist/types/DbConfigHandler.js +2 -2
  53. package/dist/types/FindParams.d.ts +14 -14
  54. package/dist/types/FindParams.js +2 -2
  55. package/dist/types/IRWSModel.d.ts +3 -3
  56. package/dist/types/IRWSModel.js +2 -2
  57. package/dist/types/ITimeSeries.d.ts +6 -6
  58. package/dist/types/ITimeSeries.js +2 -2
  59. package/exec/console.js +110 -110
  60. package/exec/db.rws.webpack.config.js +168 -168
  61. package/exec/src/cli.ts +74 -73
  62. package/exec/tsconfig.json +32 -32
  63. package/exec/webpackFilters.js +17 -17
  64. package/package.json +36 -36
  65. package/src/decorators/InverseRelation.ts +36 -36
  66. package/src/decorators/InverseTimeSeries.ts +21 -21
  67. package/src/decorators/RWSCollection.ts +27 -27
  68. package/src/decorators/Relation.ts +47 -47
  69. package/src/decorators/TrackType.ts +69 -69
  70. package/src/decorators/index.ts +7 -7
  71. package/src/empty.js +0 -0
  72. package/src/helper/DbHelper.ts +177 -177
  73. package/src/helper/FieldsHelper.ts +34 -34
  74. package/src/index.ts +36 -36
  75. package/src/models/_model.ts +29 -29
  76. package/src/models/core/RWSModel.ts +520 -520
  77. package/src/models/core/TimeSeriesModel.ts +19 -19
  78. package/src/models/index.ts +20 -20
  79. package/src/models/interfaces/IModel.ts +12 -12
  80. package/src/models/interfaces/IRWSModelServices.ts +7 -7
  81. package/src/models/interfaces/OpModelType.ts +49 -49
  82. package/src/models/types/RelationTypes.ts +25 -25
  83. package/src/models/utils/ModelUtils.ts +65 -65
  84. package/src/models/utils/PaginationUtils.ts +42 -42
  85. package/src/models/utils/RelationUtils.ts +76 -76
  86. package/src/models/utils/TimeSeriesUtils.ts +38 -38
  87. package/src/services/DBService.ts +277 -277
  88. package/src/types/DbConfigHandler.ts +12 -11
  89. package/src/types/FindParams.ts +13 -13
  90. package/src/types/IRWSModel.ts +2 -2
  91. package/src/types/ITimeSeries.ts +5 -5
  92. package/tsconfig.json +22 -22
@@ -1,400 +1,400 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.RWSModel = void 0;
13
- const decorators_1 = require("../../decorators");
14
- const FieldsHelper_1 = require("../../helper/FieldsHelper");
15
- const RelationUtils_1 = require("../utils/RelationUtils");
16
- const TimeSeriesUtils_1 = require("../utils/TimeSeriesUtils");
17
- const ModelUtils_1 = require("../utils/ModelUtils");
18
- class RWSModel {
19
- constructor(data) {
20
- if (!this.getCollection()) {
21
- throw new Error('Model must have a collection defined');
22
- }
23
- this.dbService = RWSModel.services.dbService;
24
- this.configService = RWSModel.services.configService;
25
- if (!data) {
26
- return;
27
- }
28
- if (!this.hasTimeSeries()) {
29
- this._fill(data);
30
- }
31
- else {
32
- throw new Error('Time Series not supported in synchronous constructor. Use `await Model.create(data)` static method to instantiate this model.');
33
- }
34
- }
35
- checkForInclusionWithThrow() {
36
- const constructor = this.constructor;
37
- if (!constructor.checkForInclusion(constructor.name)) {
38
- throw new Error('Model undefined: ' + constructor.name);
39
- }
40
- }
41
- static checkForInclusionWithThrow(checkModelType) {
42
- if (!this.checkForInclusion(this.name)) {
43
- throw new Error('Model undefined: ' + this.name);
44
- }
45
- }
46
- checkForInclusion() {
47
- const constructor = this.constructor;
48
- return constructor.checkForInclusion(constructor.name);
49
- }
50
- static checkForInclusion(checkModelType) {
51
- return this.loadModels().find((definedModel) => {
52
- return definedModel.name === checkModelType;
53
- }) !== undefined;
54
- }
55
- _fill(data) {
56
- for (const key in data) {
57
- if (data.hasOwnProperty(key)) {
58
- const meta = Reflect.getMetadata(`InverseTimeSeries:${key}`, this.constructor.prototype);
59
- if (meta) {
60
- data[key] = {
61
- create: data[key]
62
- };
63
- }
64
- else {
65
- this[key] = data[key];
66
- }
67
- }
68
- }
69
- return this;
70
- }
71
- hasRelation(key) {
72
- return RelationUtils_1.RelationUtils.hasRelation(this, key);
73
- }
74
- bindRelation(key, relatedModel) {
75
- return RelationUtils_1.RelationUtils.bindRelation(relatedModel);
76
- }
77
- async _asyncFill(data, fullDataMode = false, allowRelations = true) {
78
- const collections_to_models = {};
79
- const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
80
- const classFields = FieldsHelper_1.FieldsHelper.getAllClassFields(this.constructor);
81
- // Get both relation metadata types asynchronously
82
- const [relOneData, relManyData] = await Promise.all([
83
- this.getRelationOneMeta(classFields),
84
- this.getRelationManyMeta(classFields)
85
- ]);
86
- this.loadModels().forEach((model) => {
87
- collections_to_models[model.getCollection()] = model;
88
- });
89
- const seriesHydrationfields = [];
90
- if (allowRelations) {
91
- // Handle many-to-many relations
92
- for (const key in relManyData) {
93
- if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
94
- continue;
95
- }
96
- const relMeta = relManyData[key];
97
- const relationEnabled = RelationUtils_1.RelationUtils.checkRelEnabled(this, relMeta.key);
98
- if (relationEnabled) {
99
- this[relMeta.key] = await relMeta.inversionModel.findBy({
100
- conditions: {
101
- [relMeta.foreignKey]: data.id
102
- },
103
- allowRelations: false
104
- });
105
- }
106
- }
107
- // Handle one-to-one relations
108
- for (const key in relOneData) {
109
- if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
110
- continue;
111
- }
112
- const relMeta = relOneData[key];
113
- const relationEnabled = RelationUtils_1.RelationUtils.checkRelEnabled(this, relMeta.key);
114
- if (!data[relMeta.hydrationField] && relMeta.required) {
115
- throw new Error(`Relation field "${relMeta.hydrationField}" is required in model ${this.constructor.name}.`);
116
- }
117
- if (relationEnabled && data[relMeta.hydrationField]) {
118
- this[relMeta.key] = await relMeta.model.find(data[relMeta.hydrationField], { allowRelations: false });
119
- }
120
- else if (relationEnabled && !data[relMeta.hydrationField] && data[relMeta.key]) {
121
- const newRelModel = await relMeta.model.create(data[relMeta.key]);
122
- this[relMeta.key] = await newRelModel.save();
123
- }
124
- const cutKeys = this.constructor._CUT_KEYS;
125
- if (!cutKeys.includes(relMeta.hydrationField)) {
126
- cutKeys.push(relMeta.hydrationField);
127
- }
128
- }
129
- }
130
- // Process regular fields and time series
131
- for (const key in data) {
132
- if (data.hasOwnProperty(key)) {
133
- if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
134
- continue;
135
- }
136
- if (Object.keys(relOneData).includes(key)) {
137
- continue;
138
- }
139
- if (seriesHydrationfields.includes(key)) {
140
- continue;
141
- }
142
- const timeSeriesMetaData = timeSeriesIds[key];
143
- if (timeSeriesMetaData) {
144
- this[key] = data[key];
145
- const seriesModel = collections_to_models[timeSeriesMetaData.collection];
146
- const dataModels = await seriesModel.findBy({
147
- id: { in: data[key] }
148
- });
149
- seriesHydrationfields.push(timeSeriesMetaData.hydrationField);
150
- this[timeSeriesMetaData.hydrationField] = dataModels;
151
- }
152
- else {
153
- this[key] = data[key];
154
- }
155
- }
156
- }
157
- return this;
158
- }
159
- getModelScalarFields(model) {
160
- return ModelUtils_1.ModelUtils.getModelScalarFields(model);
161
- }
162
- async getRelationOneMeta(classFields) {
163
- return RelationUtils_1.RelationUtils.getRelationOneMeta(this, classFields);
164
- }
165
- static async getRelationOneMeta(model, classFields) {
166
- return RelationUtils_1.RelationUtils.getRelationOneMeta(model, classFields);
167
- }
168
- async getRelationManyMeta(classFields) {
169
- return RelationUtils_1.RelationUtils.getRelationManyMeta(this, classFields);
170
- }
171
- static async getRelationManyMeta(model, classFields) {
172
- return RelationUtils_1.RelationUtils.getRelationManyMeta(model, classFields);
173
- }
174
- static async paginate(paginateParams, findParams) {
175
- var _a, _b, _c, _d, _e;
176
- const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
177
- const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
178
- const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
179
- const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
180
- const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
181
- const collection = Reflect.get(this, '_collection');
182
- this.checkForInclusionWithThrow(this.name);
183
- try {
184
- const dbData = await this.services.dbService.findBy(collection, conditions, fields, ordering, paginateParams);
185
- if (dbData.length) {
186
- const instanced = [];
187
- for (const data of dbData) {
188
- const inst = new this();
189
- instanced.push((await inst._asyncFill(data, fullData, allowRelations)));
190
- }
191
- return instanced;
192
- }
193
- return [];
194
- }
195
- catch (rwsError) {
196
- console.error(rwsError);
197
- throw rwsError;
198
- }
199
- }
200
- async toMongo() {
201
- const data = {};
202
- const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
203
- const timeSeriesHydrationFields = [];
204
- for (const key in this) {
205
- if (this.hasRelation(key)) {
206
- data[key] = this.bindRelation(key, this[key]);
207
- continue;
208
- }
209
- if (!(await this.isDbVariable(key))) {
210
- continue;
211
- }
212
- const passedFieldCondition = this.hasOwnProperty(key) &&
213
- !(this.constructor._BANNED_KEYS
214
- || RWSModel._BANNED_KEYS).includes(key) &&
215
- !timeSeriesHydrationFields.includes(key);
216
- if (passedFieldCondition) {
217
- data[key] = this[key];
218
- }
219
- if (timeSeriesIds[key]) {
220
- data[key] = this[key];
221
- timeSeriesHydrationFields.push(timeSeriesIds[key].hydrationField);
222
- }
223
- }
224
- return data;
225
- }
226
- getCollection() {
227
- return this.constructor._collection || this._collection;
228
- }
229
- static getCollection() {
230
- return this.constructor._collection || this._collection;
231
- }
232
- async save() {
233
- const data = await this.toMongo();
234
- let updatedModelData = data;
235
- if (this.id) {
236
- this.preUpdate();
237
- updatedModelData = await this.dbService.update(data, this.getCollection());
238
- await this._asyncFill(updatedModelData);
239
- this.postUpdate();
240
- }
241
- else {
242
- this.preCreate();
243
- const isTimeSeries = false; //this instanceof timeSeriesModel;
244
- updatedModelData = await this.dbService.insert(data, this.getCollection(), isTimeSeries);
245
- await this._asyncFill(updatedModelData);
246
- this.postCreate();
247
- }
248
- return this;
249
- }
250
- static async getModelAnnotations(constructor) {
251
- return ModelUtils_1.ModelUtils.getModelAnnotations(constructor);
252
- }
253
- preUpdate() {
254
- return;
255
- }
256
- postUpdate() {
257
- return;
258
- }
259
- preCreate() {
260
- return;
261
- }
262
- postCreate() {
263
- return;
264
- }
265
- static isSubclass(constructor, baseClass) {
266
- return ModelUtils_1.ModelUtils.isSubclass(constructor, baseClass);
267
- }
268
- hasTimeSeries() {
269
- return TimeSeriesUtils_1.TimeSeriesUtils.checkTimeSeries(this.constructor);
270
- }
271
- static checkTimeSeries(constructor) {
272
- return TimeSeriesUtils_1.TimeSeriesUtils.checkTimeSeries(constructor);
273
- }
274
- async isDbVariable(variable) {
275
- return ModelUtils_1.ModelUtils.checkDbVariable(this.constructor, variable);
276
- }
277
- static async checkDbVariable(constructor, variable) {
278
- return ModelUtils_1.ModelUtils.checkDbVariable(constructor, variable);
279
- }
280
- sanitizeDBData(data) {
281
- const dataKeys = Object.keys(data);
282
- const sanitizedData = {};
283
- for (const key of dataKeys) {
284
- if (this.isDbVariable(key)) {
285
- sanitizedData[key] = data[key];
286
- }
287
- }
288
- return sanitizedData;
289
- }
290
- static async watchCollection(preRun) {
291
- const collection = Reflect.get(this, '_collection');
292
- this.checkForInclusionWithThrow(this.name);
293
- return await this.services.dbService.watchCollection(collection, preRun);
294
- }
295
- static async findOneBy(findParams) {
296
- var _a, _b, _c, _d, _e;
297
- const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
298
- const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
299
- const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
300
- const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
301
- const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
302
- this.checkForInclusionWithThrow('');
303
- const collection = Reflect.get(this, '_collection');
304
- const dbData = await this.services.dbService.findOneBy(collection, conditions, fields, ordering, allowRelations);
305
- if (dbData) {
306
- const inst = new this();
307
- return await inst._asyncFill(dbData, fullData, allowRelations);
308
- }
309
- return null;
310
- }
311
- static async find(id, findParams = null) {
312
- var _a, _b, _c, _d;
313
- const ordering = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _a !== void 0 ? _a : null;
314
- const fields = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _b !== void 0 ? _b : null;
315
- const allowRelations = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _c !== void 0 ? _c : true;
316
- const fullData = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _d !== void 0 ? _d : false;
317
- const collection = Reflect.get(this, '_collection');
318
- this.checkForInclusionWithThrow(this.name);
319
- const dbData = await this.services.dbService.findOneBy(collection, { id }, fields, ordering, allowRelations);
320
- if (dbData) {
321
- const inst = new this();
322
- return await inst._asyncFill(dbData, fullData, allowRelations);
323
- }
324
- return null;
325
- }
326
- static async findBy(findParams) {
327
- var _a, _b, _c, _d, _e;
328
- const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
329
- const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
330
- const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
331
- const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
332
- const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
333
- const collection = Reflect.get(this, '_collection');
334
- this.checkForInclusionWithThrow(this.name);
335
- try {
336
- const dbData = await this.services.dbService.findBy(collection, conditions, fields, ordering);
337
- if (dbData.length) {
338
- const instanced = [];
339
- for (const data of dbData) {
340
- const inst = new this();
341
- instanced.push((await inst._asyncFill(data, fullData, allowRelations)));
342
- }
343
- return instanced;
344
- }
345
- return [];
346
- }
347
- catch (rwsError) {
348
- console.error(rwsError);
349
- throw rwsError;
350
- }
351
- }
352
- static async delete(conditions) {
353
- const collection = Reflect.get(this, '_collection');
354
- this.checkForInclusionWithThrow(this.name);
355
- return await this.services.dbService.delete(collection, conditions);
356
- }
357
- async delete() {
358
- const collection = Reflect.get(this, '_collection');
359
- this.checkForInclusionWithThrow();
360
- return await this.dbService.delete(collection, {
361
- id: this.id
362
- });
363
- }
364
- static async create(data) {
365
- const newModel = new this();
366
- const sanitizedData = newModel.sanitizeDBData(data);
367
- await newModel._asyncFill(sanitizedData);
368
- return newModel;
369
- }
370
- static loadModels() {
371
- return this.allModels || [];
372
- }
373
- loadModels() {
374
- return RWSModel.loadModels();
375
- }
376
- checkRelEnabled(key) {
377
- return RelationUtils_1.RelationUtils.checkRelEnabled(this, key);
378
- }
379
- static setServices(services) {
380
- this.allModels = services.configService.get('db_models');
381
- this.services = services;
382
- }
383
- getDb() {
384
- return this.services.dbService;
385
- }
386
- static getDb() {
387
- return this.services.dbService;
388
- }
389
- }
390
- exports.RWSModel = RWSModel;
391
- RWSModel.services = {};
392
- RWSModel._collection = null;
393
- RWSModel._RELATIONS = {};
394
- RWSModel._BANNED_KEYS = ['_collection'];
395
- RWSModel.allModels = [];
396
- RWSModel._CUT_KEYS = [];
397
- __decorate([
398
- (0, decorators_1.TrackType)(String),
399
- __metadata("design:type", String)
400
- ], RWSModel.prototype, "id", void 0);
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RWSModel = void 0;
13
+ const decorators_1 = require("../../decorators");
14
+ const FieldsHelper_1 = require("../../helper/FieldsHelper");
15
+ const RelationUtils_1 = require("../utils/RelationUtils");
16
+ const TimeSeriesUtils_1 = require("../utils/TimeSeriesUtils");
17
+ const ModelUtils_1 = require("../utils/ModelUtils");
18
+ class RWSModel {
19
+ constructor(data) {
20
+ if (!this.getCollection()) {
21
+ throw new Error('Model must have a collection defined');
22
+ }
23
+ this.dbService = RWSModel.services.dbService;
24
+ this.configService = RWSModel.services.configService;
25
+ if (!data) {
26
+ return;
27
+ }
28
+ if (!this.hasTimeSeries()) {
29
+ this._fill(data);
30
+ }
31
+ else {
32
+ throw new Error('Time Series not supported in synchronous constructor. Use `await Model.create(data)` static method to instantiate this model.');
33
+ }
34
+ }
35
+ checkForInclusionWithThrow() {
36
+ const constructor = this.constructor;
37
+ if (!constructor.checkForInclusion(constructor.name)) {
38
+ throw new Error('Model undefined: ' + constructor.name);
39
+ }
40
+ }
41
+ static checkForInclusionWithThrow(checkModelType) {
42
+ if (!this.checkForInclusion(this.name)) {
43
+ throw new Error('Model undefined: ' + this.name);
44
+ }
45
+ }
46
+ checkForInclusion() {
47
+ const constructor = this.constructor;
48
+ return constructor.checkForInclusion(constructor.name);
49
+ }
50
+ static checkForInclusion(checkModelType) {
51
+ return this.loadModels().find((definedModel) => {
52
+ return definedModel.name === checkModelType;
53
+ }) !== undefined;
54
+ }
55
+ _fill(data) {
56
+ for (const key in data) {
57
+ if (data.hasOwnProperty(key)) {
58
+ const meta = Reflect.getMetadata(`InverseTimeSeries:${key}`, this.constructor.prototype);
59
+ if (meta) {
60
+ data[key] = {
61
+ create: data[key]
62
+ };
63
+ }
64
+ else {
65
+ this[key] = data[key];
66
+ }
67
+ }
68
+ }
69
+ return this;
70
+ }
71
+ hasRelation(key) {
72
+ return RelationUtils_1.RelationUtils.hasRelation(this, key);
73
+ }
74
+ bindRelation(key, relatedModel) {
75
+ return RelationUtils_1.RelationUtils.bindRelation(relatedModel);
76
+ }
77
+ async _asyncFill(data, fullDataMode = false, allowRelations = true) {
78
+ const collections_to_models = {};
79
+ const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
80
+ const classFields = FieldsHelper_1.FieldsHelper.getAllClassFields(this.constructor);
81
+ // Get both relation metadata types asynchronously
82
+ const [relOneData, relManyData] = await Promise.all([
83
+ this.getRelationOneMeta(classFields),
84
+ this.getRelationManyMeta(classFields)
85
+ ]);
86
+ this.loadModels().forEach((model) => {
87
+ collections_to_models[model.getCollection()] = model;
88
+ });
89
+ const seriesHydrationfields = [];
90
+ if (allowRelations) {
91
+ // Handle many-to-many relations
92
+ for (const key in relManyData) {
93
+ if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
94
+ continue;
95
+ }
96
+ const relMeta = relManyData[key];
97
+ const relationEnabled = RelationUtils_1.RelationUtils.checkRelEnabled(this, relMeta.key);
98
+ if (relationEnabled) {
99
+ this[relMeta.key] = await relMeta.inversionModel.findBy({
100
+ conditions: {
101
+ [relMeta.foreignKey]: data.id
102
+ },
103
+ allowRelations: false
104
+ });
105
+ }
106
+ }
107
+ // Handle one-to-one relations
108
+ for (const key in relOneData) {
109
+ if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
110
+ continue;
111
+ }
112
+ const relMeta = relOneData[key];
113
+ const relationEnabled = RelationUtils_1.RelationUtils.checkRelEnabled(this, relMeta.key);
114
+ if (!data[relMeta.hydrationField] && relMeta.required) {
115
+ throw new Error(`Relation field "${relMeta.hydrationField}" is required in model ${this.constructor.name}.`);
116
+ }
117
+ if (relationEnabled && data[relMeta.hydrationField]) {
118
+ this[relMeta.key] = await relMeta.model.find(data[relMeta.hydrationField], { allowRelations: false });
119
+ }
120
+ else if (relationEnabled && !data[relMeta.hydrationField] && data[relMeta.key]) {
121
+ const newRelModel = await relMeta.model.create(data[relMeta.key]);
122
+ this[relMeta.key] = await newRelModel.save();
123
+ }
124
+ const cutKeys = this.constructor._CUT_KEYS;
125
+ if (!cutKeys.includes(relMeta.hydrationField)) {
126
+ cutKeys.push(relMeta.hydrationField);
127
+ }
128
+ }
129
+ }
130
+ // Process regular fields and time series
131
+ for (const key in data) {
132
+ if (data.hasOwnProperty(key)) {
133
+ if (!fullDataMode && this.constructor._CUT_KEYS.includes(key)) {
134
+ continue;
135
+ }
136
+ if (Object.keys(relOneData).includes(key)) {
137
+ continue;
138
+ }
139
+ if (seriesHydrationfields.includes(key)) {
140
+ continue;
141
+ }
142
+ const timeSeriesMetaData = timeSeriesIds[key];
143
+ if (timeSeriesMetaData) {
144
+ this[key] = data[key];
145
+ const seriesModel = collections_to_models[timeSeriesMetaData.collection];
146
+ const dataModels = await seriesModel.findBy({
147
+ id: { in: data[key] }
148
+ });
149
+ seriesHydrationfields.push(timeSeriesMetaData.hydrationField);
150
+ this[timeSeriesMetaData.hydrationField] = dataModels;
151
+ }
152
+ else {
153
+ this[key] = data[key];
154
+ }
155
+ }
156
+ }
157
+ return this;
158
+ }
159
+ getModelScalarFields(model) {
160
+ return ModelUtils_1.ModelUtils.getModelScalarFields(model);
161
+ }
162
+ async getRelationOneMeta(classFields) {
163
+ return RelationUtils_1.RelationUtils.getRelationOneMeta(this, classFields);
164
+ }
165
+ static async getRelationOneMeta(model, classFields) {
166
+ return RelationUtils_1.RelationUtils.getRelationOneMeta(model, classFields);
167
+ }
168
+ async getRelationManyMeta(classFields) {
169
+ return RelationUtils_1.RelationUtils.getRelationManyMeta(this, classFields);
170
+ }
171
+ static async getRelationManyMeta(model, classFields) {
172
+ return RelationUtils_1.RelationUtils.getRelationManyMeta(model, classFields);
173
+ }
174
+ static async paginate(paginateParams, findParams) {
175
+ var _a, _b, _c, _d, _e;
176
+ const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
177
+ const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
178
+ const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
179
+ const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
180
+ const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
181
+ const collection = Reflect.get(this, '_collection');
182
+ this.checkForInclusionWithThrow(this.name);
183
+ try {
184
+ const dbData = await this.services.dbService.findBy(collection, conditions, fields, ordering, paginateParams);
185
+ if (dbData.length) {
186
+ const instanced = [];
187
+ for (const data of dbData) {
188
+ const inst = new this();
189
+ instanced.push((await inst._asyncFill(data, fullData, allowRelations)));
190
+ }
191
+ return instanced;
192
+ }
193
+ return [];
194
+ }
195
+ catch (rwsError) {
196
+ console.error(rwsError);
197
+ throw rwsError;
198
+ }
199
+ }
200
+ async toMongo() {
201
+ const data = {};
202
+ const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
203
+ const timeSeriesHydrationFields = [];
204
+ for (const key in this) {
205
+ if (this.hasRelation(key)) {
206
+ data[key] = this.bindRelation(key, this[key]);
207
+ continue;
208
+ }
209
+ if (!(await this.isDbVariable(key))) {
210
+ continue;
211
+ }
212
+ const passedFieldCondition = this.hasOwnProperty(key) &&
213
+ !(this.constructor._BANNED_KEYS
214
+ || RWSModel._BANNED_KEYS).includes(key) &&
215
+ !timeSeriesHydrationFields.includes(key);
216
+ if (passedFieldCondition) {
217
+ data[key] = this[key];
218
+ }
219
+ if (timeSeriesIds[key]) {
220
+ data[key] = this[key];
221
+ timeSeriesHydrationFields.push(timeSeriesIds[key].hydrationField);
222
+ }
223
+ }
224
+ return data;
225
+ }
226
+ getCollection() {
227
+ return this.constructor._collection || this._collection;
228
+ }
229
+ static getCollection() {
230
+ return this.constructor._collection || this._collection;
231
+ }
232
+ async save() {
233
+ const data = await this.toMongo();
234
+ let updatedModelData = data;
235
+ if (this.id) {
236
+ this.preUpdate();
237
+ updatedModelData = await this.dbService.update(data, this.getCollection());
238
+ await this._asyncFill(updatedModelData);
239
+ this.postUpdate();
240
+ }
241
+ else {
242
+ this.preCreate();
243
+ const isTimeSeries = false; //this instanceof timeSeriesModel;
244
+ updatedModelData = await this.dbService.insert(data, this.getCollection(), isTimeSeries);
245
+ await this._asyncFill(updatedModelData);
246
+ this.postCreate();
247
+ }
248
+ return this;
249
+ }
250
+ static async getModelAnnotations(constructor) {
251
+ return ModelUtils_1.ModelUtils.getModelAnnotations(constructor);
252
+ }
253
+ preUpdate() {
254
+ return;
255
+ }
256
+ postUpdate() {
257
+ return;
258
+ }
259
+ preCreate() {
260
+ return;
261
+ }
262
+ postCreate() {
263
+ return;
264
+ }
265
+ static isSubclass(constructor, baseClass) {
266
+ return ModelUtils_1.ModelUtils.isSubclass(constructor, baseClass);
267
+ }
268
+ hasTimeSeries() {
269
+ return TimeSeriesUtils_1.TimeSeriesUtils.checkTimeSeries(this.constructor);
270
+ }
271
+ static checkTimeSeries(constructor) {
272
+ return TimeSeriesUtils_1.TimeSeriesUtils.checkTimeSeries(constructor);
273
+ }
274
+ async isDbVariable(variable) {
275
+ return ModelUtils_1.ModelUtils.checkDbVariable(this.constructor, variable);
276
+ }
277
+ static async checkDbVariable(constructor, variable) {
278
+ return ModelUtils_1.ModelUtils.checkDbVariable(constructor, variable);
279
+ }
280
+ sanitizeDBData(data) {
281
+ const dataKeys = Object.keys(data);
282
+ const sanitizedData = {};
283
+ for (const key of dataKeys) {
284
+ if (this.isDbVariable(key)) {
285
+ sanitizedData[key] = data[key];
286
+ }
287
+ }
288
+ return sanitizedData;
289
+ }
290
+ static async watchCollection(preRun) {
291
+ const collection = Reflect.get(this, '_collection');
292
+ this.checkForInclusionWithThrow(this.name);
293
+ return await this.services.dbService.watchCollection(collection, preRun);
294
+ }
295
+ static async findOneBy(findParams) {
296
+ var _a, _b, _c, _d, _e;
297
+ const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
298
+ const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
299
+ const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
300
+ const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
301
+ const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
302
+ this.checkForInclusionWithThrow('');
303
+ const collection = Reflect.get(this, '_collection');
304
+ const dbData = await this.services.dbService.findOneBy(collection, conditions, fields, ordering, allowRelations);
305
+ if (dbData) {
306
+ const inst = new this();
307
+ return await inst._asyncFill(dbData, fullData, allowRelations);
308
+ }
309
+ return null;
310
+ }
311
+ static async find(id, findParams = null) {
312
+ var _a, _b, _c, _d;
313
+ const ordering = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _a !== void 0 ? _a : null;
314
+ const fields = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _b !== void 0 ? _b : null;
315
+ const allowRelations = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _c !== void 0 ? _c : true;
316
+ const fullData = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _d !== void 0 ? _d : false;
317
+ const collection = Reflect.get(this, '_collection');
318
+ this.checkForInclusionWithThrow(this.name);
319
+ const dbData = await this.services.dbService.findOneBy(collection, { id }, fields, ordering, allowRelations);
320
+ if (dbData) {
321
+ const inst = new this();
322
+ return await inst._asyncFill(dbData, fullData, allowRelations);
323
+ }
324
+ return null;
325
+ }
326
+ static async findBy(findParams) {
327
+ var _a, _b, _c, _d, _e;
328
+ const conditions = (_a = findParams === null || findParams === void 0 ? void 0 : findParams.conditions) !== null && _a !== void 0 ? _a : {};
329
+ const ordering = (_b = findParams === null || findParams === void 0 ? void 0 : findParams.ordering) !== null && _b !== void 0 ? _b : null;
330
+ const fields = (_c = findParams === null || findParams === void 0 ? void 0 : findParams.fields) !== null && _c !== void 0 ? _c : null;
331
+ const allowRelations = (_d = findParams === null || findParams === void 0 ? void 0 : findParams.allowRelations) !== null && _d !== void 0 ? _d : true;
332
+ const fullData = (_e = findParams === null || findParams === void 0 ? void 0 : findParams.fullData) !== null && _e !== void 0 ? _e : false;
333
+ const collection = Reflect.get(this, '_collection');
334
+ this.checkForInclusionWithThrow(this.name);
335
+ try {
336
+ const dbData = await this.services.dbService.findBy(collection, conditions, fields, ordering);
337
+ if (dbData.length) {
338
+ const instanced = [];
339
+ for (const data of dbData) {
340
+ const inst = new this();
341
+ instanced.push((await inst._asyncFill(data, fullData, allowRelations)));
342
+ }
343
+ return instanced;
344
+ }
345
+ return [];
346
+ }
347
+ catch (rwsError) {
348
+ console.error(rwsError);
349
+ throw rwsError;
350
+ }
351
+ }
352
+ static async delete(conditions) {
353
+ const collection = Reflect.get(this, '_collection');
354
+ this.checkForInclusionWithThrow(this.name);
355
+ return await this.services.dbService.delete(collection, conditions);
356
+ }
357
+ async delete() {
358
+ const collection = Reflect.get(this, '_collection');
359
+ this.checkForInclusionWithThrow();
360
+ return await this.dbService.delete(collection, {
361
+ id: this.id
362
+ });
363
+ }
364
+ static async create(data) {
365
+ const newModel = new this();
366
+ const sanitizedData = newModel.sanitizeDBData(data);
367
+ await newModel._asyncFill(sanitizedData);
368
+ return newModel;
369
+ }
370
+ static loadModels() {
371
+ return this.allModels || [];
372
+ }
373
+ loadModels() {
374
+ return RWSModel.loadModels();
375
+ }
376
+ checkRelEnabled(key) {
377
+ return RelationUtils_1.RelationUtils.checkRelEnabled(this, key);
378
+ }
379
+ static setServices(services) {
380
+ this.allModels = services.configService.get('db_models');
381
+ this.services = services;
382
+ }
383
+ getDb() {
384
+ return this.services.dbService;
385
+ }
386
+ static getDb() {
387
+ return this.services.dbService;
388
+ }
389
+ }
390
+ exports.RWSModel = RWSModel;
391
+ RWSModel.services = {};
392
+ RWSModel._collection = null;
393
+ RWSModel._RELATIONS = {};
394
+ RWSModel._BANNED_KEYS = ['_collection'];
395
+ RWSModel.allModels = [];
396
+ RWSModel._CUT_KEYS = [];
397
+ __decorate([
398
+ (0, decorators_1.TrackType)(String),
399
+ __metadata("design:type", String)
400
+ ], RWSModel.prototype, "id", void 0);