@webda/core 3.5.0 → 3.7.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 +13 -0
- package/lib/core.js +58 -2
- package/lib/core.js.map +1 -1
- package/lib/core.spec.js +10 -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/aclmodel.d.ts +23 -10
- package/lib/models/aclmodel.js +31 -21
- package/lib/models/aclmodel.js.map +1 -1
- package/lib/models/aclmodel.spec.js +20 -6
- package/lib/models/aclmodel.spec.js.map +1 -1
- package/lib/models/coremodel.d.ts +106 -14
- package/lib/models/coremodel.js +240 -42
- 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/ownermodel.js +1 -1
- package/lib/models/ownermodel.js.map +1 -1
- package/lib/models/relations.d.ts +20 -20
- package/lib/models/relations.js +31 -11
- package/lib/models/relations.js.map +1 -1
- package/lib/models/relations.spec.d.ts +11 -0
- package/lib/models/relations.spec.js +115 -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/configuration.d.ts +1 -1
- package/lib/services/configuration.js +2 -1
- package/lib/services/configuration.js.map +1 -1
- package/lib/services/domainservice.d.ts +2 -1
- package/lib/services/domainservice.js +16 -25
- 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.js +1 -1
- package/lib/services/invitationservice.js.map +1 -1
- package/lib/services/invitationservice.spec.js +3 -1
- package/lib/services/invitationservice.spec.js.map +1 -1
- package/lib/services/service.d.ts +4 -5
- package/lib/services/service.js +9 -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/file.spec.js +1 -1
- package/lib/stores/file.spec.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.d.ts +4 -0
- package/lib/stores/memory.js +8 -0
- package/lib/stores/memory.js.map +1 -1
- package/lib/stores/memory.spec.d.ts +1 -0
- package/lib/stores/memory.spec.js +34 -3
- package/lib/stores/memory.spec.js.map +1 -1
- package/lib/stores/modelmapper.d.ts +21 -0
- package/lib/stores/modelmapper.js +127 -0
- package/lib/stores/modelmapper.js.map +1 -0
- package/lib/stores/store.d.ts +27 -9
- package/lib/stores/store.js +136 -82
- 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 +15 -2
- package/lib/utils/context.js +24 -5
- 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/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
- package/test/data/binaries/123/Test_plop_456 +0 -0
- package/test/data/binaries/123/data +0 -1
- package/test/data/tasks/068e6a96-9fdc-44e2-80fa-d27ed28f5440.json +0 -1
- package/test/data/tasks/task_no_owner.json +0 -1
- package/test/data/tasks/task_public.json +0 -1
- package/test/data/tasks/task_user1.json +0 -1
- package/test/data/tasks/task_user2.json +0 -1
- package/test/my-cnf.json +0 -11
package/lib/stores/store.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Counter, EventWithContext, Histogram } from "../core.js";
|
|
2
2
|
import { ConfigurationProvider, WebdaError } from "../index.js";
|
|
3
|
-
import { Constructor, CoreModel, CoreModelDefinition,
|
|
3
|
+
import { Constructor, CoreModel, CoreModelDefinition, FilterAttributes } from "../models/coremodel.js";
|
|
4
4
|
import { Service, ServiceParameters } from "../services/service.js";
|
|
5
5
|
import { OperationContext, WebContext } from "../utils/context.js";
|
|
6
6
|
import { HttpMethodType } from "../utils/httpcontext.js";
|
|
@@ -358,6 +358,14 @@ export declare class StoreParameters extends ServiceParameters {
|
|
|
358
358
|
* @default "Webda/CoreModel"
|
|
359
359
|
*/
|
|
360
360
|
model?: string;
|
|
361
|
+
/**
|
|
362
|
+
* Additional models
|
|
363
|
+
*
|
|
364
|
+
* Allow this store to manage other models
|
|
365
|
+
*
|
|
366
|
+
* @default []
|
|
367
|
+
*/
|
|
368
|
+
additionalModels?: string[];
|
|
361
369
|
/**
|
|
362
370
|
* async delete
|
|
363
371
|
*/
|
|
@@ -594,10 +602,10 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
594
602
|
* @param info
|
|
595
603
|
* @returns
|
|
596
604
|
*/
|
|
597
|
-
incrementAttributes<FK extends
|
|
605
|
+
incrementAttributes<FK extends FilterAttributes<T, number>>(uid: string, info: {
|
|
598
606
|
property: FK;
|
|
599
607
|
value: number;
|
|
600
|
-
}[]): Promise<
|
|
608
|
+
}[]): Promise<Date>;
|
|
601
609
|
/**
|
|
602
610
|
* Helper function that call incrementAttributes
|
|
603
611
|
* @param uid
|
|
@@ -605,7 +613,7 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
605
613
|
* @param value
|
|
606
614
|
* @returns
|
|
607
615
|
*/
|
|
608
|
-
incrementAttribute<FK extends
|
|
616
|
+
incrementAttribute<FK extends FilterAttributes<T, number>>(uid: string, prop: FK, value: number): Promise<Date>;
|
|
609
617
|
/**
|
|
610
618
|
* Add or update an item to an array in the model
|
|
611
619
|
*
|
|
@@ -616,7 +624,7 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
616
624
|
* @param itemWriteCondition value of the condition to test (in case of update)
|
|
617
625
|
* @param itemWriteConditionField field to read the condition from (in case of update)
|
|
618
626
|
*/
|
|
619
|
-
upsertItemToCollection<FK extends
|
|
627
|
+
upsertItemToCollection<FK extends FilterAttributes<T, Array<any>>>(uid: string, prop: FK, item: any, index?: number, itemWriteCondition?: any, itemWriteConditionField?: string): Promise<Date>;
|
|
620
628
|
/**
|
|
621
629
|
* Remove an item from an array in the model
|
|
622
630
|
*
|
|
@@ -626,15 +634,25 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
626
634
|
* @param itemWriteCondition value of the condition
|
|
627
635
|
* @param itemWriteConditionField field to read the condition from
|
|
628
636
|
*/
|
|
629
|
-
deleteItemFromCollection<FK extends
|
|
637
|
+
deleteItemFromCollection<FK extends FilterAttributes<T, Array<any>>>(uid: string, prop: FK, index: number, itemWriteCondition: any, itemWriteConditionField?: string): Promise<Date>;
|
|
630
638
|
/**
|
|
631
|
-
*
|
|
639
|
+
* Iterate through the results
|
|
632
640
|
*
|
|
633
641
|
* This can be resource consuming
|
|
634
642
|
*
|
|
635
643
|
* @param query
|
|
636
644
|
* @param context
|
|
637
645
|
*/
|
|
646
|
+
iterate(query?: string, context?: OperationContext): AsyncGenerator<T>;
|
|
647
|
+
/**
|
|
648
|
+
* Query all the results
|
|
649
|
+
*
|
|
650
|
+
*
|
|
651
|
+
* @param query
|
|
652
|
+
* @param context
|
|
653
|
+
* @returns
|
|
654
|
+
* @deprecated use iterate instead
|
|
655
|
+
*/
|
|
638
656
|
queryAll(query: string, context?: OperationContext): Promise<T[]>;
|
|
639
657
|
/**
|
|
640
658
|
* Check that __type Comparison is only used with = and CONTAINS
|
|
@@ -695,7 +713,7 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
695
713
|
* @param condition
|
|
696
714
|
* @param uid
|
|
697
715
|
*/
|
|
698
|
-
checkCollectionUpdateCondition<FK extends
|
|
716
|
+
checkCollectionUpdateCondition<FK extends FilterAttributes<T, Array<any>>, CK extends keyof T>(model: T, collection: FK, conditionField?: CK, condition?: any, index?: number): void;
|
|
699
717
|
/**
|
|
700
718
|
* Update conditionally
|
|
701
719
|
* @param uuid
|
|
@@ -714,7 +732,7 @@ declare abstract class Store<T extends CoreModel = CoreModel, K extends StorePar
|
|
|
714
732
|
* @param itemWriteConditionField
|
|
715
733
|
* @param updateDate
|
|
716
734
|
*/
|
|
717
|
-
simulateUpsertItemToCollection<FK extends
|
|
735
|
+
simulateUpsertItemToCollection<FK extends FilterAttributes<T, Array<any>>>(model: T, prop: FK, item: any, updateDate: Date, index?: number, itemWriteCondition?: any, itemWriteConditionField?: string): Promise<void>;
|
|
718
736
|
/**
|
|
719
737
|
* Update an object
|
|
720
738
|
*
|
package/lib/stores/store.js
CHANGED
|
@@ -57,6 +57,7 @@ export class StoreParameters extends ServiceParameters {
|
|
|
57
57
|
this.forceModel ?? (this.forceModel = false);
|
|
58
58
|
this.slowQueryThreshold ?? (this.slowQueryThreshold = 30000);
|
|
59
59
|
this.modelAliases ?? (this.modelAliases = {});
|
|
60
|
+
this.additionalModels ?? (this.additionalModels = []);
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
@@ -139,6 +140,21 @@ class Store extends Service {
|
|
|
139
140
|
if (!this.parameters.strict) {
|
|
140
141
|
recursive(this._model.getHierarchy().children, 1);
|
|
141
142
|
}
|
|
143
|
+
// Add additional models
|
|
144
|
+
if (this.parameters.additionalModels.length) {
|
|
145
|
+
// Strict mode is to only allow one model per store
|
|
146
|
+
if (this.parameters.strict) {
|
|
147
|
+
this.log("ERROR", "Cannot add additional models in strict mode");
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
for (let modelType of this.parameters.additionalModels) {
|
|
151
|
+
const model = app.getModel(modelType);
|
|
152
|
+
this._modelsHierarchy[model.getIdentifier(false)] = 0;
|
|
153
|
+
this._modelsHierarchy[model.getIdentifier()] = 0;
|
|
154
|
+
recursive(model.getHierarchy().children, 1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
142
158
|
if (this.getParameters().expose) {
|
|
143
159
|
this.log("WARN", "Exposing a store is not recommended, use a DomainService instead to expose all your CoreModel");
|
|
144
160
|
}
|
|
@@ -306,16 +322,16 @@ class Store extends Service {
|
|
|
306
322
|
let executer;
|
|
307
323
|
if (action.global) {
|
|
308
324
|
// By default will grab the object and then call the action
|
|
309
|
-
if (!this._model[name]
|
|
310
|
-
throw Error("Action static method
|
|
325
|
+
if (!this._model[name]) {
|
|
326
|
+
throw Error("Action static method " + name + " does not exist");
|
|
311
327
|
}
|
|
312
328
|
executer = this.httpGlobalAction;
|
|
313
329
|
this.addRoute(`./${name}`, action.methods, executer, action.openapi);
|
|
314
330
|
}
|
|
315
331
|
else {
|
|
316
332
|
// By default will grab the object and then call the action
|
|
317
|
-
if (!this._model.prototype[name]
|
|
318
|
-
throw Error("Action method
|
|
333
|
+
if (!this._model.prototype[name]) {
|
|
334
|
+
throw Error("Action method " + name + " does not exist");
|
|
319
335
|
}
|
|
320
336
|
executer = this.httpAction;
|
|
321
337
|
this.addRoute(`./{uuid}/${name}`, action.methods, executer, action.openapi);
|
|
@@ -371,12 +387,7 @@ class Store extends Service {
|
|
|
371
387
|
*/
|
|
372
388
|
initModel(object = {}) {
|
|
373
389
|
var _a;
|
|
374
|
-
|
|
375
|
-
object.__type ?? (object.__type = this.getWebda().getApplication().getModelFromInstance(object) || this._modelType);
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
object.__type ?? (object.__type = this._modelType);
|
|
379
|
-
}
|
|
390
|
+
object.__type ?? (object.__type = this.getWebda().getApplication().getModelFromInstance(object) || this._modelType);
|
|
380
391
|
// Make sure to send a model object
|
|
381
392
|
if (!(object instanceof this._model)) {
|
|
382
393
|
// Dynamic load type
|
|
@@ -391,11 +402,11 @@ class Store extends Service {
|
|
|
391
402
|
if (!this.parameters.defaultModel) {
|
|
392
403
|
throw new Error(`Unknown model ${object.__type} found for Store(${this.getName()})`);
|
|
393
404
|
}
|
|
394
|
-
object = this._model.factory(
|
|
405
|
+
object = this._model.factory(object);
|
|
395
406
|
}
|
|
396
407
|
}
|
|
397
408
|
else {
|
|
398
|
-
object = this._model.factory(
|
|
409
|
+
object = this._model.factory(object);
|
|
399
410
|
}
|
|
400
411
|
}
|
|
401
412
|
if (!object.getUuid()) {
|
|
@@ -455,7 +466,7 @@ class Store extends Service {
|
|
|
455
466
|
this.metrics.operations_total.inc({ operation: "increment" });
|
|
456
467
|
await this._incrementAttributes(uid, params, updateDate);
|
|
457
468
|
await this._cacheStore?._incrementAttributes(uid, params, updateDate);
|
|
458
|
-
|
|
469
|
+
this.emitSync("Store.PartialUpdated", {
|
|
459
470
|
object_id: uid,
|
|
460
471
|
store: this,
|
|
461
472
|
updateDate,
|
|
@@ -463,6 +474,7 @@ class Store extends Service {
|
|
|
463
474
|
increments: params
|
|
464
475
|
}
|
|
465
476
|
});
|
|
477
|
+
return updateDate;
|
|
466
478
|
}
|
|
467
479
|
/**
|
|
468
480
|
* Helper function that call incrementAttributes
|
|
@@ -501,6 +513,7 @@ class Store extends Service {
|
|
|
501
513
|
}
|
|
502
514
|
}
|
|
503
515
|
});
|
|
516
|
+
return updateDate;
|
|
504
517
|
}
|
|
505
518
|
/**
|
|
506
519
|
* Remove an item from an array in the model
|
|
@@ -527,29 +540,48 @@ class Store extends Service {
|
|
|
527
540
|
}
|
|
528
541
|
}
|
|
529
542
|
});
|
|
543
|
+
return updateDate;
|
|
530
544
|
}
|
|
531
545
|
/**
|
|
532
|
-
*
|
|
546
|
+
* Iterate through the results
|
|
533
547
|
*
|
|
534
548
|
* This can be resource consuming
|
|
535
549
|
*
|
|
536
550
|
* @param query
|
|
537
551
|
* @param context
|
|
538
552
|
*/
|
|
539
|
-
async
|
|
540
|
-
const res = [];
|
|
553
|
+
async *iterate(query = "", context) {
|
|
541
554
|
if (query.includes("OFFSET")) {
|
|
542
|
-
throw new Error("Cannot contain an OFFSET for
|
|
555
|
+
throw new Error("Cannot contain an OFFSET for iterate method");
|
|
543
556
|
}
|
|
544
557
|
let continuationToken;
|
|
545
558
|
do {
|
|
546
559
|
let q = query + (continuationToken !== undefined ? ` OFFSET "${continuationToken}"` : "");
|
|
547
560
|
let page = await this.query(q, context);
|
|
561
|
+
for (let item of page.results) {
|
|
562
|
+
yield item;
|
|
563
|
+
}
|
|
548
564
|
continuationToken = page.continuationToken;
|
|
549
|
-
res.push(...page.results);
|
|
550
565
|
} while (continuationToken);
|
|
566
|
+
}
|
|
567
|
+
// REFACTOR . >= 4
|
|
568
|
+
/**
|
|
569
|
+
* Query all the results
|
|
570
|
+
*
|
|
571
|
+
*
|
|
572
|
+
* @param query
|
|
573
|
+
* @param context
|
|
574
|
+
* @returns
|
|
575
|
+
* @deprecated use iterate instead
|
|
576
|
+
*/
|
|
577
|
+
async queryAll(query, context) {
|
|
578
|
+
let res = [];
|
|
579
|
+
for await (let item of this.iterate(query, context)) {
|
|
580
|
+
res.push(item);
|
|
581
|
+
}
|
|
551
582
|
return res;
|
|
552
583
|
}
|
|
584
|
+
// END_REFACTOR
|
|
553
585
|
/**
|
|
554
586
|
* Check that __type Comparison is only used with = and CONTAINS
|
|
555
587
|
* If CONTAINS is used, move __type to __types
|
|
@@ -718,30 +750,42 @@ class Store extends Service {
|
|
|
718
750
|
async create(object, ctx = undefined) {
|
|
719
751
|
object = this.initModel(object);
|
|
720
752
|
// Dates should be store by the Store
|
|
721
|
-
|
|
722
|
-
|
|
753
|
+
if (!object._creationDate) {
|
|
754
|
+
object._creationDate = object._lastUpdate = new Date();
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
object._lastUpdate = new Date();
|
|
758
|
+
}
|
|
723
759
|
const ancestors = this.getWebda().getApplication().getModelHierarchy(object.__type).ancestors;
|
|
724
760
|
object.__types = [object.__type, ...ancestors].filter(i => i !== "Webda/CoreModel" && i !== "CoreModel");
|
|
725
761
|
if (ctx) {
|
|
726
762
|
object.setContext(ctx);
|
|
727
763
|
}
|
|
728
|
-
|
|
764
|
+
// Handle object auto listener
|
|
765
|
+
const evt = {
|
|
729
766
|
object: object,
|
|
730
767
|
store: this,
|
|
731
768
|
context: ctx
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
|
|
769
|
+
};
|
|
770
|
+
await Promise.all([
|
|
771
|
+
this.emitSync("Store.Save", evt),
|
|
772
|
+
object?.__class.emitSync("Store.Save", evt),
|
|
773
|
+
object._onSave()
|
|
774
|
+
]);
|
|
735
775
|
this.metrics.operations_total.inc({ operation: "save" });
|
|
736
776
|
let res = await this._save(object);
|
|
737
777
|
await this._cacheStore?._save(object);
|
|
738
778
|
object = this.initModel(res);
|
|
739
|
-
|
|
779
|
+
const evtSaved = {
|
|
740
780
|
object: object,
|
|
741
781
|
store: this,
|
|
742
782
|
context: ctx
|
|
743
|
-
}
|
|
744
|
-
await
|
|
783
|
+
};
|
|
784
|
+
await Promise.all([
|
|
785
|
+
this.emitSync("Store.Saved", evtSaved),
|
|
786
|
+
object?.__class.emitSync("Store.Saved", evtSaved),
|
|
787
|
+
object._onSaved()
|
|
788
|
+
]);
|
|
745
789
|
return object;
|
|
746
790
|
}
|
|
747
791
|
/**
|
|
@@ -872,21 +916,16 @@ class Store extends Service {
|
|
|
872
916
|
if (object instanceof CoreModel) {
|
|
873
917
|
loaded.setContext(object.getContext());
|
|
874
918
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
store: this,
|
|
886
|
-
update: object
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
await loaded._onUpdate(object);
|
|
919
|
+
const evt = {
|
|
920
|
+
object: loaded,
|
|
921
|
+
store: this,
|
|
922
|
+
update: object
|
|
923
|
+
};
|
|
924
|
+
await Promise.all([
|
|
925
|
+
this.emitSync(partial ? `Store.PatchUpdate` : `Store.Update`, evt),
|
|
926
|
+
object?.__class?.emitSync(partial ? `Store.PatchUpdate` : `Store.Update`, evt),
|
|
927
|
+
loaded._onUpdate(object)
|
|
928
|
+
]);
|
|
890
929
|
let res;
|
|
891
930
|
if (conditionField !== null) {
|
|
892
931
|
conditionField ?? (conditionField = "_lastUpdate");
|
|
@@ -916,19 +955,15 @@ class Store extends Service {
|
|
|
916
955
|
loaded[i] = object[i];
|
|
917
956
|
}
|
|
918
957
|
saved = this.initModel(loaded);
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
store: this
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
await saved._onUpdated();
|
|
958
|
+
const evtUpdated = {
|
|
959
|
+
object: saved,
|
|
960
|
+
store: this
|
|
961
|
+
};
|
|
962
|
+
await Promise.all([
|
|
963
|
+
this.emitSync(partial ? `Store.PatchUpdated` : `Store.Updated`, evtUpdated),
|
|
964
|
+
saved?.__class.emitSync(partial ? `Store.PatchUpdated` : `Store.Updated`, evtUpdated),
|
|
965
|
+
saved._onUpdated()
|
|
966
|
+
]);
|
|
932
967
|
return saved;
|
|
933
968
|
}
|
|
934
969
|
/**
|
|
@@ -1133,12 +1168,16 @@ class Store extends Service {
|
|
|
1133
1168
|
throw new UpdateConditionFailError(to_delete.getUuid(), writeConditionField, writeCondition);
|
|
1134
1169
|
}
|
|
1135
1170
|
}
|
|
1136
|
-
|
|
1137
|
-
await this.emitSync("Store.Delete", {
|
|
1171
|
+
const evt = {
|
|
1138
1172
|
object: to_delete,
|
|
1139
1173
|
store: this
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1174
|
+
};
|
|
1175
|
+
// Send preevent
|
|
1176
|
+
await Promise.all([
|
|
1177
|
+
this.emitSync("Store.Delete", evt),
|
|
1178
|
+
to_delete?.__class.emitSync("Store.Delete", evt),
|
|
1179
|
+
to_delete._onDelete()
|
|
1180
|
+
]);
|
|
1142
1181
|
// If async we just tag the object as deleted
|
|
1143
1182
|
if (this.parameters.asyncDelete && !sync) {
|
|
1144
1183
|
this.metrics.operations_total.inc({ operation: "partialUpdate" });
|
|
@@ -1156,11 +1195,15 @@ class Store extends Service {
|
|
|
1156
1195
|
await this._cacheStore?._delete(to_delete.getUuid(), writeCondition, writeConditionField);
|
|
1157
1196
|
}
|
|
1158
1197
|
// Send post event
|
|
1159
|
-
|
|
1198
|
+
const evtDeleted = {
|
|
1160
1199
|
object: to_delete,
|
|
1161
1200
|
store: this
|
|
1162
|
-
}
|
|
1163
|
-
await
|
|
1201
|
+
};
|
|
1202
|
+
await Promise.all([
|
|
1203
|
+
this.emitSync("Store.Deleted", evtDeleted),
|
|
1204
|
+
to_delete.__class.emitSync("Store.Deleted", evtDeleted),
|
|
1205
|
+
to_delete._onDeleted()
|
|
1206
|
+
]);
|
|
1164
1207
|
}
|
|
1165
1208
|
/**
|
|
1166
1209
|
* By default we cannot know if the store will trigger or not
|
|
@@ -1224,12 +1267,12 @@ class Store extends Service {
|
|
|
1224
1267
|
}
|
|
1225
1268
|
object = this.initModel(object);
|
|
1226
1269
|
object.setContext(ctx);
|
|
1227
|
-
|
|
1270
|
+
const evt = {
|
|
1228
1271
|
object: object,
|
|
1229
1272
|
store: this,
|
|
1230
1273
|
context: ctx
|
|
1231
|
-
}
|
|
1232
|
-
await object._onGet();
|
|
1274
|
+
};
|
|
1275
|
+
await Promise.all([this.emitSync("Store.Get", evt), object.__class.emitSync("Store.Get", evt), object._onGet()]);
|
|
1233
1276
|
return object;
|
|
1234
1277
|
}
|
|
1235
1278
|
/**
|
|
@@ -1328,7 +1371,7 @@ class Store extends Service {
|
|
|
1328
1371
|
async operationCreate(ctx, model) {
|
|
1329
1372
|
let body = await ctx.getInput();
|
|
1330
1373
|
const modelPrototype = this.getWebda().getApplication().getModel(model);
|
|
1331
|
-
let object = modelPrototype.factory(
|
|
1374
|
+
let object = modelPrototype.factory(body, ctx);
|
|
1332
1375
|
object._creationDate = new Date();
|
|
1333
1376
|
await object.checkAct(ctx, "create");
|
|
1334
1377
|
try {
|
|
@@ -1343,12 +1386,13 @@ class Store extends Service {
|
|
|
1343
1386
|
}
|
|
1344
1387
|
await this.save(object, ctx);
|
|
1345
1388
|
ctx.write(object);
|
|
1346
|
-
|
|
1389
|
+
const evt = {
|
|
1347
1390
|
context: ctx,
|
|
1348
1391
|
values: body,
|
|
1349
1392
|
object: object,
|
|
1350
1393
|
store: this
|
|
1351
|
-
}
|
|
1394
|
+
};
|
|
1395
|
+
await Promise.all([object.__class.emitSync("Store.WebCreate", evt), this.emitSync("Store.WebCreate", evt)]);
|
|
1352
1396
|
}
|
|
1353
1397
|
/**
|
|
1354
1398
|
* Handle obect action
|
|
@@ -1361,23 +1405,28 @@ class Store extends Service {
|
|
|
1361
1405
|
throw new WebdaError.NotFound("Object not found or is deleted");
|
|
1362
1406
|
}
|
|
1363
1407
|
await object.checkAct(ctx, action);
|
|
1364
|
-
|
|
1408
|
+
const evt = {
|
|
1365
1409
|
action: action,
|
|
1366
1410
|
object: object,
|
|
1367
1411
|
store: this,
|
|
1368
1412
|
context: ctx
|
|
1369
|
-
}
|
|
1413
|
+
};
|
|
1414
|
+
await Promise.all([this.emitSync("Store.Action", evt), object.__class.emitSync("Store.Action", evt)]);
|
|
1370
1415
|
const res = await object[action](ctx);
|
|
1371
1416
|
if (res) {
|
|
1372
1417
|
ctx.write(res);
|
|
1373
1418
|
}
|
|
1374
|
-
|
|
1419
|
+
const evtActioned = {
|
|
1375
1420
|
action: action,
|
|
1376
1421
|
object: object,
|
|
1377
1422
|
store: this,
|
|
1378
1423
|
context: ctx,
|
|
1379
1424
|
result: res
|
|
1380
|
-
}
|
|
1425
|
+
};
|
|
1426
|
+
await Promise.all([
|
|
1427
|
+
this.emitSync("Store.Actioned", evtActioned),
|
|
1428
|
+
object?.__class.emitSync("Store.Actioned", evtActioned)
|
|
1429
|
+
]);
|
|
1381
1430
|
}
|
|
1382
1431
|
/**
|
|
1383
1432
|
* Handle collection action
|
|
@@ -1385,23 +1434,25 @@ class Store extends Service {
|
|
|
1385
1434
|
*/
|
|
1386
1435
|
async httpGlobalAction(ctx, model = this._model) {
|
|
1387
1436
|
let action = ctx.getHttpContext().getUrl().split("/").pop();
|
|
1388
|
-
|
|
1437
|
+
const evt = {
|
|
1389
1438
|
action: action,
|
|
1390
1439
|
store: this,
|
|
1391
1440
|
context: ctx,
|
|
1392
1441
|
model
|
|
1393
|
-
}
|
|
1442
|
+
};
|
|
1443
|
+
await Promise.all([this.emitSync("Store.Action", evt), model.emitSync("Store.Action", evt)]);
|
|
1394
1444
|
const res = await model[action](ctx);
|
|
1395
1445
|
if (res) {
|
|
1396
1446
|
ctx.write(res);
|
|
1397
1447
|
}
|
|
1398
|
-
|
|
1448
|
+
const evtActioned = {
|
|
1399
1449
|
action: action,
|
|
1400
1450
|
store: this,
|
|
1401
1451
|
context: ctx,
|
|
1402
1452
|
result: res,
|
|
1403
1453
|
model
|
|
1404
|
-
}
|
|
1454
|
+
};
|
|
1455
|
+
await Promise.all([this.emitSync("Store.Actioned", evtActioned), model?.emitSync("Store.Actioned", evtActioned)]);
|
|
1405
1456
|
}
|
|
1406
1457
|
/**
|
|
1407
1458
|
* Handle HTTP Update for an object
|
|
@@ -1457,13 +1508,14 @@ class Store extends Service {
|
|
|
1457
1508
|
object = await this.update(updateObject);
|
|
1458
1509
|
}
|
|
1459
1510
|
ctx.write(object);
|
|
1460
|
-
|
|
1511
|
+
const evt = {
|
|
1461
1512
|
context: ctx,
|
|
1462
1513
|
updates: body,
|
|
1463
1514
|
object: object,
|
|
1464
1515
|
store: this,
|
|
1465
1516
|
method: ctx.getHttpContext().getMethod()
|
|
1466
|
-
}
|
|
1517
|
+
};
|
|
1518
|
+
await Promise.all([object?.__class.emitSync("Store.WebUpdate", evt), this.emitSync("Store.WebUpdate", evt)]);
|
|
1467
1519
|
}
|
|
1468
1520
|
/**
|
|
1469
1521
|
* Handle GET on object
|
|
@@ -1483,11 +1535,12 @@ class Store extends Service {
|
|
|
1483
1535
|
}
|
|
1484
1536
|
await object.checkAct(ctx, "get");
|
|
1485
1537
|
ctx.write(object);
|
|
1486
|
-
|
|
1538
|
+
const evt = {
|
|
1487
1539
|
context: ctx,
|
|
1488
1540
|
object: object,
|
|
1489
1541
|
store: this
|
|
1490
|
-
}
|
|
1542
|
+
};
|
|
1543
|
+
await Promise.all([this.emitSync("Store.WebGet", evt), object.__class.emitSync("Store.WebGet", evt)]);
|
|
1491
1544
|
ctx.write(object);
|
|
1492
1545
|
}
|
|
1493
1546
|
/**
|
|
@@ -1507,11 +1560,12 @@ class Store extends Service {
|
|
|
1507
1560
|
// Might still run into: Have trouble to handle the Content-Length on API Gateway so returning an empty object for now
|
|
1508
1561
|
ctx.writeHead(204, { "Content-Length": "0" });
|
|
1509
1562
|
await this.delete(uuid);
|
|
1510
|
-
|
|
1563
|
+
const evt = {
|
|
1511
1564
|
context: ctx,
|
|
1512
1565
|
object_id: uuid,
|
|
1513
1566
|
store: this
|
|
1514
|
-
}
|
|
1567
|
+
};
|
|
1568
|
+
await Promise.all([this.emitSync("Store.WebDelete", evt), object.__class.emitSync("Store.WebDelete", evt)]);
|
|
1515
1569
|
}
|
|
1516
1570
|
/**
|
|
1517
1571
|
* Return the model uuid field
|