@webda/core 3.6.0 → 3.8.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 +7 -1
- package/lib/application.js.map +1 -1
- package/lib/core.d.ts +9 -0
- package/lib/core.js +44 -1
- package/lib/core.js.map +1 -1
- package/lib/core.spec.js +5 -4
- package/lib/core.spec.js.map +1 -1
- package/lib/index.d.ts +5 -4
- package/lib/index.js +5 -4
- package/lib/index.js.map +1 -1
- package/lib/models/coremodel.d.ts +103 -12
- package/lib/models/coremodel.js +230 -33
- package/lib/models/coremodel.js.map +1 -1
- package/lib/models/coremodel.spec.js +21 -4
- package/lib/models/coremodel.spec.js.map +1 -1
- package/lib/models/ident.d.ts +2 -6
- package/lib/models/ident.js.map +1 -1
- package/lib/models/ident.spec.js.map +1 -1
- package/lib/models/relations.d.ts +24 -14
- package/lib/models/relations.js +36 -8
- package/lib/models/relations.js.map +1 -1
- package/lib/models/relations.spec.d.ts +12 -0
- package/lib/models/relations.spec.js +223 -0
- package/lib/models/relations.spec.js.map +1 -0
- package/lib/models/user.d.ts +2 -2
- package/lib/models/user.js.map +1 -1
- package/lib/services/asyncevents.d.ts +4 -3
- package/lib/services/asyncevents.js +17 -4
- package/lib/services/asyncevents.js.map +1 -1
- package/lib/services/authentication.js +1 -1
- package/lib/services/authentication.js.map +1 -1
- package/lib/services/binary.d.ts +26 -2
- package/lib/services/binary.js +160 -63
- package/lib/services/binary.js.map +1 -1
- package/lib/services/binary.spec.js +3 -1
- package/lib/services/binary.spec.js.map +1 -1
- package/lib/services/cloudbinary.d.ts +0 -18
- package/lib/services/cloudbinary.js +0 -94
- package/lib/services/cloudbinary.js.map +1 -1
- package/lib/services/cloudbinary.spec.js +18 -11
- package/lib/services/cloudbinary.spec.js.map +1 -1
- package/lib/services/domainservice.d.ts +2 -1
- package/lib/services/domainservice.js +13 -22
- package/lib/services/domainservice.js.map +1 -1
- package/lib/services/filebinary.js +1 -1
- package/lib/services/filebinary.js.map +1 -1
- package/lib/services/filebinary.spec.d.ts +1 -0
- package/lib/services/filebinary.spec.js +24 -2
- package/lib/services/filebinary.spec.js.map +1 -1
- package/lib/services/invitationservice.spec.js +3 -1
- package/lib/services/invitationservice.spec.js.map +1 -1
- package/lib/services/prometheus.js +1 -0
- package/lib/services/prometheus.js.map +1 -1
- package/lib/services/service.d.ts +0 -5
- package/lib/services/service.js +3 -34
- package/lib/services/service.js.map +1 -1
- package/lib/services/service.spec.js +2 -2
- package/lib/services/service.spec.js.map +1 -1
- package/lib/stores/aliasstore.js +5 -1
- package/lib/stores/aliasstore.js.map +1 -1
- package/lib/stores/file.js.map +1 -1
- package/lib/stores/mapper.d.ts +4 -4
- package/lib/stores/mapper.spec.js +1 -1
- package/lib/stores/mapper.spec.js.map +1 -1
- package/lib/stores/memory.spec.d.ts +1 -0
- package/lib/stores/memory.spec.js +28 -1
- package/lib/stores/memory.spec.js.map +1 -1
- package/lib/stores/modelmapper.d.ts +61 -0
- package/lib/stores/modelmapper.js +199 -0
- package/lib/stores/modelmapper.js.map +1 -0
- package/lib/stores/store.d.ts +33 -11
- package/lib/stores/store.js +155 -95
- package/lib/stores/store.js.map +1 -1
- package/lib/stores/store.spec.js +2 -2
- package/lib/stores/store.spec.js.map +1 -1
- package/lib/test.js +1 -1
- package/lib/test.js.map +1 -1
- package/lib/utils/case.d.ts +7 -0
- package/lib/utils/case.js +43 -0
- package/lib/utils/case.js.map +1 -0
- package/lib/utils/case.spec.d.ts +1 -0
- package/lib/utils/case.spec.js +50 -0
- package/lib/utils/case.spec.js.map +1 -0
- package/lib/utils/context.d.ts +3 -2
- package/lib/utils/context.js +6 -2
- package/lib/utils/context.js.map +1 -1
- package/lib/utils/cookie.spec.js +2 -2
- package/lib/utils/cookie.spec.js.map +1 -1
- package/lib/utils/esm.d.ts +9 -0
- package/lib/utils/esm.js +9 -0
- package/lib/utils/esm.js.map +1 -1
- package/lib/utils/httpcontext.d.ts +1 -1
- package/lib/utils/httpcontext.js +1 -0
- package/lib/utils/httpcontext.js.map +1 -1
- package/lib/utils/logger.spec.js +5 -2
- package/lib/utils/logger.spec.js.map +1 -1
- package/lib/utils/serializers.js +8 -1
- package/lib/utils/serializers.js.map +1 -1
- package/lib/utils/serializers.spec.js +6 -0
- package/lib/utils/serializers.spec.js.map +1 -1
- package/lib/utils/session.spec.js +1 -1
- package/lib/utils/session.spec.js.map +1 -1
- package/lib/utils/throttler.d.ts +22 -2
- package/lib/utils/throttler.js +35 -3
- package/lib/utils/throttler.js.map +1 -1
- package/lib/utils/throttler.spec.js +10 -2
- package/lib/utils/throttler.spec.js.map +1 -1
- package/package.json +10 -10
- package/webda.module.json +60 -26
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from "events";
|
|
1
3
|
import { JSONSchema7 } from "json-schema";
|
|
2
4
|
import { ModelGraph, ModelsTree } from "../application.js";
|
|
3
5
|
import { Core } from "../core.js";
|
|
4
6
|
import { Service } from "../services/service.js";
|
|
5
|
-
import { Store } from "../stores/store.js";
|
|
7
|
+
import { Store, StoreEvents } from "../stores/store.js";
|
|
6
8
|
import { OperationContext } from "../utils/context.js";
|
|
7
9
|
import { HttpMethodType } from "../utils/httpcontext.js";
|
|
8
10
|
import { ModelActions, RawModel } from "./relations.js";
|
|
@@ -15,10 +17,18 @@ import { ModelActions, RawModel } from "./relations.js";
|
|
|
15
17
|
* @returns
|
|
16
18
|
*/
|
|
17
19
|
export declare function Expose(params?: Partial<ExposeParameters>): (target: CoreModelDefinition) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Attribute of an object
|
|
22
|
+
*
|
|
23
|
+
* Filter out methods
|
|
24
|
+
*/
|
|
25
|
+
export type Attributes<T extends object> = {
|
|
26
|
+
[K in keyof T]: T[K] extends Function ? never : K;
|
|
27
|
+
}[keyof T];
|
|
18
28
|
/**
|
|
19
29
|
* Filter type keys by type
|
|
20
30
|
*/
|
|
21
|
-
export type
|
|
31
|
+
export type FilterAttributes<T extends CoreModel, K> = {
|
|
22
32
|
[L in keyof T]: T[L] extends K ? L : never;
|
|
23
33
|
}[keyof T];
|
|
24
34
|
/**
|
|
@@ -107,7 +117,7 @@ export interface CoreModelDefinition<T extends CoreModel = CoreModel> {
|
|
|
107
117
|
* @param object to load data from
|
|
108
118
|
* @param context if the data is unsafe from http
|
|
109
119
|
*/
|
|
110
|
-
factory
|
|
120
|
+
factory<T extends CoreModel>(this: Constructor<T>, object: Partial<T>, context?: OperationContext): T;
|
|
111
121
|
/**
|
|
112
122
|
* Get the model actions
|
|
113
123
|
*/
|
|
@@ -172,10 +182,17 @@ export interface CoreModelDefinition<T extends CoreModel = CoreModel> {
|
|
|
172
182
|
results: T[];
|
|
173
183
|
continuationToken?: string;
|
|
174
184
|
}>;
|
|
185
|
+
on<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, listener: (evt: StoreEvents[Key]) => any, async?: boolean): void;
|
|
186
|
+
onAsync<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, listener: (evt: StoreEvents[Key]) => any): any;
|
|
187
|
+
emit<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, evt: StoreEvents[Key]): any;
|
|
188
|
+
emitSync<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, evt: StoreEvents[Key]): Promise<void>;
|
|
175
189
|
}
|
|
176
190
|
export type Constructor<T, K extends Array<any> = []> = new (...args: K) => T;
|
|
177
191
|
/**
|
|
178
192
|
* Make a property hidden from json
|
|
193
|
+
*
|
|
194
|
+
* This property will not be saved in the store
|
|
195
|
+
*
|
|
179
196
|
* @param target
|
|
180
197
|
* @param propertyKey
|
|
181
198
|
*/
|
|
@@ -200,18 +217,18 @@ export declare class ModelRef<T extends CoreModel> {
|
|
|
200
217
|
toString(): string;
|
|
201
218
|
toJSON(): string;
|
|
202
219
|
getUuid(): string;
|
|
203
|
-
deleteItemFromCollection(prop:
|
|
204
|
-
upsertItemToCollection(prop:
|
|
220
|
+
deleteItemFromCollection(prop: FilterAttributes<T, any[]>, index: number, itemWriteCondition: any, itemWriteConditionField?: string): Promise<this>;
|
|
221
|
+
upsertItemToCollection(prop: FilterAttributes<T, any[]>, item: any, index?: number, itemWriteCondition?: any, itemWriteConditionField?: string): Promise<this>;
|
|
205
222
|
exists(): Promise<boolean>;
|
|
206
223
|
delete(): Promise<void>;
|
|
207
224
|
conditionalPatch(updates: Partial<T>, conditionField: any, condition: any): Promise<boolean>;
|
|
208
225
|
patch(updates: Partial<T>): Promise<boolean>;
|
|
209
|
-
setAttribute(attribute: keyof T, value: any): Promise<
|
|
210
|
-
removeAttribute(attribute: keyof T, itemWriteCondition?: any, itemWriteConditionField?: keyof T): Promise<
|
|
226
|
+
setAttribute(attribute: keyof T, value: any): Promise<this>;
|
|
227
|
+
removeAttribute(attribute: keyof T, itemWriteCondition?: any, itemWriteConditionField?: keyof T): Promise<this>;
|
|
211
228
|
incrementAttributes(info: {
|
|
212
|
-
property:
|
|
229
|
+
property: FilterAttributes<T, number>;
|
|
213
230
|
value: number;
|
|
214
|
-
}[]): Promise<
|
|
231
|
+
}[]): Promise<this>;
|
|
215
232
|
}
|
|
216
233
|
export declare class ModelRefWithCreate<T extends CoreModel> extends ModelRef<T> {
|
|
217
234
|
/**
|
|
@@ -240,6 +257,7 @@ export declare class ModelRefCustom<T extends CoreModel> extends ModelRef<T> {
|
|
|
240
257
|
getUuid(): string;
|
|
241
258
|
}
|
|
242
259
|
export type ModelRefCustomProperties<T extends CoreModel, K> = ModelRefCustom<T> & K;
|
|
260
|
+
export declare const Emitters: WeakMap<Constructor<CoreModel>, EventEmitter>;
|
|
243
261
|
/**
|
|
244
262
|
* Basic Object in Webda
|
|
245
263
|
*
|
|
@@ -254,7 +272,7 @@ declare class CoreModel {
|
|
|
254
272
|
/**
|
|
255
273
|
* Class reference to the object
|
|
256
274
|
*/
|
|
257
|
-
__class: CoreModelDefinition
|
|
275
|
+
__class: CoreModelDefinition<this>;
|
|
258
276
|
/**
|
|
259
277
|
* Type name
|
|
260
278
|
*/
|
|
@@ -291,6 +309,33 @@ declare class CoreModel {
|
|
|
291
309
|
*/
|
|
292
310
|
__deleted: boolean;
|
|
293
311
|
constructor();
|
|
312
|
+
/**
|
|
313
|
+
* Listen to events on the model
|
|
314
|
+
* @param event
|
|
315
|
+
* @param listener
|
|
316
|
+
* @param async
|
|
317
|
+
*/
|
|
318
|
+
static on<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, listener: (evt: StoreEvents[Key]) => any, async?: boolean): void;
|
|
319
|
+
/**
|
|
320
|
+
* Emit an event for this class
|
|
321
|
+
* @param this
|
|
322
|
+
* @param event
|
|
323
|
+
* @param evt
|
|
324
|
+
*/
|
|
325
|
+
static emit<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, evt: StoreEvents[Key]): void;
|
|
326
|
+
/**
|
|
327
|
+
* Emit an event for this class and wait for all listeners to finish
|
|
328
|
+
* @param this
|
|
329
|
+
* @param event
|
|
330
|
+
* @param evt
|
|
331
|
+
*/
|
|
332
|
+
static emitSync<T extends CoreModel, Key extends keyof StoreEvents>(this: Constructor<T>, event: Key, evt: StoreEvents[Key]): Promise<void>;
|
|
333
|
+
/**
|
|
334
|
+
* Listen to events on the model asynchronously
|
|
335
|
+
* @param event
|
|
336
|
+
* @param listener
|
|
337
|
+
*/
|
|
338
|
+
static onAsync<Key extends keyof StoreEvents>(event: Key, listener: (evt: StoreEvents[Key]) => any): void;
|
|
294
339
|
/**
|
|
295
340
|
*
|
|
296
341
|
* @returns
|
|
@@ -383,6 +428,22 @@ declare class CoreModel {
|
|
|
383
428
|
* @param prefix
|
|
384
429
|
*/
|
|
385
430
|
static flat(target: any, data: any, split?: string, prefix?: string): any;
|
|
431
|
+
/**
|
|
432
|
+
* Complete the query with __type/__types
|
|
433
|
+
* @param query
|
|
434
|
+
* @param includeSubclass
|
|
435
|
+
* @returns
|
|
436
|
+
*/
|
|
437
|
+
protected static completeQuery(query: string, includeSubclass?: boolean): string;
|
|
438
|
+
/**
|
|
439
|
+
* Iterate through the model
|
|
440
|
+
* @param this
|
|
441
|
+
* @param query
|
|
442
|
+
* @param includeSubclass
|
|
443
|
+
* @param context
|
|
444
|
+
* @returns
|
|
445
|
+
*/
|
|
446
|
+
static iterate<T extends CoreModel>(this: Constructor<T>, query?: string, includeSubclass?: boolean, context?: OperationContext): AsyncGenerator<T>;
|
|
386
447
|
/**
|
|
387
448
|
* Query for models
|
|
388
449
|
* @param this
|
|
@@ -444,7 +505,7 @@ declare class CoreModel {
|
|
|
444
505
|
* Create an object
|
|
445
506
|
* @returns
|
|
446
507
|
*/
|
|
447
|
-
static factory
|
|
508
|
+
static factory<T extends CoreModel>(this: Constructor<T>, object: Partial<T>, context?: OperationContext): T;
|
|
448
509
|
/**
|
|
449
510
|
* Detect what looks like a CoreModel but can be from different version
|
|
450
511
|
* @param object
|
|
@@ -485,7 +546,7 @@ declare class CoreModel {
|
|
|
485
546
|
* @param raw data
|
|
486
547
|
* @param secure if false will ignore any _ variable
|
|
487
548
|
*/
|
|
488
|
-
load(raw: RawModel<this>, secure?: boolean): this;
|
|
549
|
+
load(raw: RawModel<this>, secure?: boolean, relations?: boolean): this;
|
|
489
550
|
/**
|
|
490
551
|
* Patch every attribute that is based on a relation
|
|
491
552
|
* to add all the helpers
|
|
@@ -608,6 +669,36 @@ declare class CoreModel {
|
|
|
608
669
|
* Called when object is updated
|
|
609
670
|
*/
|
|
610
671
|
_onUpdated(): Promise<void>;
|
|
672
|
+
/**
|
|
673
|
+
* Set attribute on the object and database
|
|
674
|
+
* @param property
|
|
675
|
+
* @param value
|
|
676
|
+
*/
|
|
677
|
+
setAttribute(property: keyof this, value: any): Promise<void>;
|
|
678
|
+
/**
|
|
679
|
+
* Remove attribute from both the object and db
|
|
680
|
+
* @param property
|
|
681
|
+
*/
|
|
682
|
+
removeAttribute(property: keyof this): Promise<void>;
|
|
683
|
+
/**
|
|
684
|
+
* Increment an attribute both in store and object
|
|
685
|
+
* @param property
|
|
686
|
+
* @param value
|
|
687
|
+
*/
|
|
688
|
+
incrementAttribute(property: FilterAttributes<this, number>, value: number): Promise<void>;
|
|
689
|
+
/**
|
|
690
|
+
* Return a model ref
|
|
691
|
+
* @returns
|
|
692
|
+
*/
|
|
693
|
+
getRef<T extends this>(): ModelRef<T>;
|
|
694
|
+
/**
|
|
695
|
+
* Increment a attributes both in store and object
|
|
696
|
+
* @param info
|
|
697
|
+
*/
|
|
698
|
+
incrementAttributes(info: {
|
|
699
|
+
property: string;
|
|
700
|
+
value: number;
|
|
701
|
+
}[]): Promise<void>;
|
|
611
702
|
}
|
|
612
703
|
/**
|
|
613
704
|
* CoreModel with a uuid
|
package/lib/models/coremodel.js
CHANGED
|
@@ -4,9 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
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;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
import { EventEmitter } from "events";
|
|
7
8
|
import util from "util";
|
|
8
9
|
import { v4 as uuidv4 } from "uuid";
|
|
9
|
-
import { Core } from "../core.js";
|
|
10
|
+
import { Core, EventEmitterUtils } from "../core.js";
|
|
10
11
|
import { WebdaError } from "../errors.js";
|
|
11
12
|
import { BinariesImpl, Binary } from "../services/binary.js";
|
|
12
13
|
import { Throttler } from "../utils/throttler.js";
|
|
@@ -68,23 +69,29 @@ class CoreModelQuery {
|
|
|
68
69
|
async forEach(callback, query, context, parallelism = 3) {
|
|
69
70
|
const throttler = new Throttler();
|
|
70
71
|
throttler.setConcurrency(parallelism);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for (const model of result.results) {
|
|
76
|
-
throttler.queue(() => callback(model));
|
|
77
|
-
}
|
|
78
|
-
await throttler.waitForCompletion();
|
|
79
|
-
} while (continuationToken);
|
|
72
|
+
for await (const model of this.iterate(query, context)) {
|
|
73
|
+
throttler.execute(() => callback(model));
|
|
74
|
+
}
|
|
75
|
+
return throttler.wait();
|
|
80
76
|
}
|
|
81
77
|
/**
|
|
82
|
-
*
|
|
78
|
+
* Iterate through all
|
|
83
79
|
* @param context
|
|
84
80
|
* @returns
|
|
85
81
|
*/
|
|
86
|
-
|
|
87
|
-
return Core.get().getModelStore(this.getTargetModel()).
|
|
82
|
+
iterate(query, context) {
|
|
83
|
+
return Core.get().getModelStore(this.getTargetModel()).iterate(this.completeQuery(query), context);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get all the objects
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
89
|
+
async getAll(context) {
|
|
90
|
+
let res = [];
|
|
91
|
+
for await (const item of this.iterate(this.completeQuery(), context)) {
|
|
92
|
+
res.push(item);
|
|
93
|
+
}
|
|
94
|
+
return res;
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
__decorate([
|
|
@@ -101,6 +108,9 @@ __decorate([
|
|
|
101
108
|
], CoreModelQuery.prototype, "targetModel", void 0);
|
|
102
109
|
/**
|
|
103
110
|
* Make a property hidden from json
|
|
111
|
+
*
|
|
112
|
+
* This property will not be saved in the store
|
|
113
|
+
*
|
|
104
114
|
* @param target
|
|
105
115
|
* @param propertyKey
|
|
106
116
|
*/
|
|
@@ -151,6 +161,7 @@ export class ModelRef {
|
|
|
151
161
|
}
|
|
152
162
|
set(id) {
|
|
153
163
|
this.uuid = id instanceof CoreModel ? id.getUuid() : id;
|
|
164
|
+
this.parent?.__dirty.add(Object.keys(this.parent).find(k => this.parent[k] === this));
|
|
154
165
|
}
|
|
155
166
|
toString() {
|
|
156
167
|
return this.uuid;
|
|
@@ -161,11 +172,36 @@ export class ModelRef {
|
|
|
161
172
|
getUuid() {
|
|
162
173
|
return this.uuid;
|
|
163
174
|
}
|
|
164
|
-
deleteItemFromCollection(prop, index, itemWriteCondition, itemWriteConditionField) {
|
|
165
|
-
|
|
175
|
+
async deleteItemFromCollection(prop, index, itemWriteCondition, itemWriteConditionField) {
|
|
176
|
+
const updateDate = await this.store.deleteItemFromCollection(this.uuid, prop, index, itemWriteCondition, itemWriteConditionField);
|
|
177
|
+
await this.model.emitSync("Store.PartialUpdated", {
|
|
178
|
+
object_id: this.uuid,
|
|
179
|
+
store: this.store,
|
|
180
|
+
updateDate,
|
|
181
|
+
partial_update: {
|
|
182
|
+
deleteItem: {
|
|
183
|
+
property: prop,
|
|
184
|
+
index: index
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
return this;
|
|
166
189
|
}
|
|
167
|
-
upsertItemToCollection(prop, item, index, itemWriteCondition, itemWriteConditionField) {
|
|
168
|
-
|
|
190
|
+
async upsertItemToCollection(prop, item, index, itemWriteCondition, itemWriteConditionField) {
|
|
191
|
+
const updateDate = await this.store.upsertItemToCollection(this.uuid, prop, item, index, itemWriteCondition, itemWriteConditionField);
|
|
192
|
+
await this.model.emitSync("Store.PartialUpdated", {
|
|
193
|
+
object_id: this.uuid,
|
|
194
|
+
store: this.store,
|
|
195
|
+
updateDate,
|
|
196
|
+
partial_update: {
|
|
197
|
+
addItem: {
|
|
198
|
+
value: item,
|
|
199
|
+
property: prop,
|
|
200
|
+
index: index
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
return this;
|
|
169
205
|
}
|
|
170
206
|
exists() {
|
|
171
207
|
return this.store.exists(this.uuid);
|
|
@@ -179,14 +215,32 @@ export class ModelRef {
|
|
|
179
215
|
patch(updates) {
|
|
180
216
|
return this.store.conditionalPatch(this.uuid, updates, null, undefined);
|
|
181
217
|
}
|
|
182
|
-
setAttribute(attribute, value) {
|
|
183
|
-
|
|
218
|
+
async setAttribute(attribute, value) {
|
|
219
|
+
await this.store.setAttribute(this.uuid, attribute, value);
|
|
220
|
+
return this;
|
|
184
221
|
}
|
|
185
|
-
removeAttribute(attribute, itemWriteCondition, itemWriteConditionField) {
|
|
186
|
-
|
|
222
|
+
async removeAttribute(attribute, itemWriteCondition, itemWriteConditionField) {
|
|
223
|
+
await this.store.removeAttribute(this.uuid, attribute, itemWriteCondition, itemWriteConditionField);
|
|
224
|
+
await this.model?.emitSync("Store.PartialUpdated", {
|
|
225
|
+
object_id: this.uuid,
|
|
226
|
+
store: this.store,
|
|
227
|
+
partial_update: {
|
|
228
|
+
deleteAttribute: attribute
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
return this;
|
|
187
232
|
}
|
|
188
|
-
incrementAttributes(info) {
|
|
189
|
-
|
|
233
|
+
async incrementAttributes(info) {
|
|
234
|
+
const updateDate = await this.store.incrementAttributes(this.uuid, info);
|
|
235
|
+
await this.model.emitSync("Store.PartialUpdated", {
|
|
236
|
+
object_id: this.uuid,
|
|
237
|
+
store: this.store,
|
|
238
|
+
updateDate,
|
|
239
|
+
partial_update: {
|
|
240
|
+
increments: info
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return this;
|
|
190
244
|
}
|
|
191
245
|
}
|
|
192
246
|
__decorate([
|
|
@@ -239,6 +293,7 @@ export class ModelRefCustom extends ModelRef {
|
|
|
239
293
|
return this.uuid;
|
|
240
294
|
}
|
|
241
295
|
}
|
|
296
|
+
export const Emitters = new WeakMap();
|
|
242
297
|
/**
|
|
243
298
|
* Basic Object in Webda
|
|
244
299
|
*
|
|
@@ -262,6 +317,78 @@ class CoreModel {
|
|
|
262
317
|
?.getApplication()
|
|
263
318
|
.getShortId(Core.get()?.getApplication().getModelFromInstance(this));
|
|
264
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Listen to events on the model
|
|
322
|
+
* @param event
|
|
323
|
+
* @param listener
|
|
324
|
+
* @param async
|
|
325
|
+
*/
|
|
326
|
+
static on(event, listener, async = false) {
|
|
327
|
+
if (!Emitters.has(this)) {
|
|
328
|
+
Emitters.set(this, new EventEmitter());
|
|
329
|
+
}
|
|
330
|
+
// TODO Manage async
|
|
331
|
+
if (async) {
|
|
332
|
+
Core.get()
|
|
333
|
+
.getService("AsyncEvents")
|
|
334
|
+
.bindAsyncListener(this, event, listener);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
Emitters.get(this).on(event, listener);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Emit an event for this class
|
|
342
|
+
* @param this
|
|
343
|
+
* @param event
|
|
344
|
+
* @param evt
|
|
345
|
+
*/
|
|
346
|
+
static emit(event, evt) {
|
|
347
|
+
let clazz = this;
|
|
348
|
+
// @ts-ignore
|
|
349
|
+
while (clazz) {
|
|
350
|
+
// Emit for all parent class
|
|
351
|
+
if (Emitters.has(clazz)) {
|
|
352
|
+
EventEmitterUtils.emit(Emitters.get(clazz), event, evt);
|
|
353
|
+
}
|
|
354
|
+
// @ts-ignore
|
|
355
|
+
if (clazz === CoreModel) {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
clazz = Object.getPrototypeOf(clazz);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Emit an event for this class and wait for all listeners to finish
|
|
363
|
+
* @param this
|
|
364
|
+
* @param event
|
|
365
|
+
* @param evt
|
|
366
|
+
*/
|
|
367
|
+
static async emitSync(event, evt) {
|
|
368
|
+
let clazz = this;
|
|
369
|
+
let p = [];
|
|
370
|
+
// @ts-ignore
|
|
371
|
+
while (clazz) {
|
|
372
|
+
// Emit for all parent class
|
|
373
|
+
if (Emitters.has(clazz)) {
|
|
374
|
+
p.push(EventEmitterUtils.emitSync(Emitters.get(clazz), event, evt));
|
|
375
|
+
}
|
|
376
|
+
// @ts-ignore
|
|
377
|
+
if (clazz === CoreModel) {
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
clazz = Object.getPrototypeOf(clazz);
|
|
381
|
+
}
|
|
382
|
+
await Promise.all(p);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Listen to events on the model asynchronously
|
|
386
|
+
* @param event
|
|
387
|
+
* @param listener
|
|
388
|
+
*/
|
|
389
|
+
static onAsync(event, listener) {
|
|
390
|
+
this.on(event, listener, true);
|
|
391
|
+
}
|
|
265
392
|
/**
|
|
266
393
|
*
|
|
267
394
|
* @returns
|
|
@@ -407,12 +534,12 @@ class CoreModel {
|
|
|
407
534
|
}
|
|
408
535
|
}
|
|
409
536
|
/**
|
|
410
|
-
*
|
|
411
|
-
* @param
|
|
412
|
-
* @param
|
|
537
|
+
* Complete the query with __type/__types
|
|
538
|
+
* @param query
|
|
539
|
+
* @param includeSubclass
|
|
413
540
|
* @returns
|
|
414
541
|
*/
|
|
415
|
-
static
|
|
542
|
+
static completeQuery(query, includeSubclass = true) {
|
|
416
543
|
if (!query.includes("__type")) {
|
|
417
544
|
if (query.trim() !== "") {
|
|
418
545
|
query = ` AND ${query}`;
|
|
@@ -426,8 +553,29 @@ class CoreModel {
|
|
|
426
553
|
query = `__type = "${name}"${query}`;
|
|
427
554
|
}
|
|
428
555
|
}
|
|
556
|
+
return query;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Iterate through the model
|
|
560
|
+
* @param this
|
|
561
|
+
* @param query
|
|
562
|
+
* @param includeSubclass
|
|
563
|
+
* @param context
|
|
564
|
+
* @returns
|
|
565
|
+
*/
|
|
566
|
+
static iterate(query = "", includeSubclass = true, context) {
|
|
567
|
+
// @ts-ignore
|
|
568
|
+
return this.store().iterate(this.completeQuery(query, includeSubclass), context);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Query for models
|
|
572
|
+
* @param this
|
|
573
|
+
* @param id
|
|
574
|
+
* @returns
|
|
575
|
+
*/
|
|
576
|
+
static async query(query = "", includeSubclass = true, context) {
|
|
429
577
|
// @ts-ignore
|
|
430
|
-
return this.store().query(query, context);
|
|
578
|
+
return this.store().query(this.completeQuery(query, includeSubclass), context);
|
|
431
579
|
}
|
|
432
580
|
/**
|
|
433
581
|
* Return a proxy to the object to detect if dirty
|
|
@@ -553,8 +701,8 @@ class CoreModel {
|
|
|
553
701
|
* Create an object
|
|
554
702
|
* @returns
|
|
555
703
|
*/
|
|
556
|
-
static factory(
|
|
557
|
-
return new
|
|
704
|
+
static factory(object, context) {
|
|
705
|
+
return object instanceof this ? object : new this().setContext(context).load(object, context === undefined);
|
|
558
706
|
}
|
|
559
707
|
/**
|
|
560
708
|
* Detect what looks like a CoreModel but can be from different version
|
|
@@ -614,7 +762,7 @@ class CoreModel {
|
|
|
614
762
|
* @param raw data
|
|
615
763
|
* @param secure if false will ignore any _ variable
|
|
616
764
|
*/
|
|
617
|
-
load(raw, secure = false) {
|
|
765
|
+
load(raw, secure = false, relations = true) {
|
|
618
766
|
// Object assign with filter
|
|
619
767
|
for (let prop in raw) {
|
|
620
768
|
let val = raw[prop];
|
|
@@ -636,7 +784,9 @@ class CoreModel {
|
|
|
636
784
|
if (!this.getUuid()) {
|
|
637
785
|
this.setUuid(this.generateUid(raw));
|
|
638
786
|
}
|
|
639
|
-
|
|
787
|
+
if (relations) {
|
|
788
|
+
this.handleRelations();
|
|
789
|
+
}
|
|
640
790
|
return this;
|
|
641
791
|
}
|
|
642
792
|
/**
|
|
@@ -740,7 +890,7 @@ class CoreModel {
|
|
|
740
890
|
* @throws Error if the object is not coming from a store
|
|
741
891
|
*/
|
|
742
892
|
async delete() {
|
|
743
|
-
return this.__store.delete(this
|
|
893
|
+
return this.__store.delete(this);
|
|
744
894
|
}
|
|
745
895
|
/**
|
|
746
896
|
* Patch current object with this update
|
|
@@ -846,6 +996,9 @@ class CoreModel {
|
|
|
846
996
|
if (value instanceof ModelRef) {
|
|
847
997
|
obj[i] = value.toString();
|
|
848
998
|
}
|
|
999
|
+
else if (value instanceof Binary) {
|
|
1000
|
+
obj[i] = value.toJSON();
|
|
1001
|
+
}
|
|
849
1002
|
else {
|
|
850
1003
|
obj[i] = value;
|
|
851
1004
|
}
|
|
@@ -904,6 +1057,50 @@ class CoreModel {
|
|
|
904
1057
|
async _onUpdated() {
|
|
905
1058
|
// Empty to be overriden
|
|
906
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Set attribute on the object and database
|
|
1062
|
+
* @param property
|
|
1063
|
+
* @param value
|
|
1064
|
+
*/
|
|
1065
|
+
async setAttribute(property, value) {
|
|
1066
|
+
await this.getRef().setAttribute(property, value);
|
|
1067
|
+
this[property] = value;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Remove attribute from both the object and db
|
|
1071
|
+
* @param property
|
|
1072
|
+
*/
|
|
1073
|
+
async removeAttribute(property) {
|
|
1074
|
+
await this.getRef().removeAttribute(property);
|
|
1075
|
+
delete this[property];
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Increment an attribute both in store and object
|
|
1079
|
+
* @param property
|
|
1080
|
+
* @param value
|
|
1081
|
+
*/
|
|
1082
|
+
async incrementAttribute(property, value) {
|
|
1083
|
+
return this.incrementAttributes([{ property, value }]);
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Return a model ref
|
|
1087
|
+
* @returns
|
|
1088
|
+
*/
|
|
1089
|
+
getRef() {
|
|
1090
|
+
return new ModelRef(this.getUuid(), this.__class);
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Increment a attributes both in store and object
|
|
1094
|
+
* @param info
|
|
1095
|
+
*/
|
|
1096
|
+
async incrementAttributes(info) {
|
|
1097
|
+
var _a;
|
|
1098
|
+
await this.getRef().incrementAttributes(info);
|
|
1099
|
+
for (let inc of info) {
|
|
1100
|
+
this[_a = inc.property] ?? (this[_a] = 0);
|
|
1101
|
+
this[inc.property] += inc.value;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
907
1104
|
}
|
|
908
1105
|
__decorate([
|
|
909
1106
|
NotEnumerable
|