@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.
Files changed (129) hide show
  1. package/lib/application.d.ts +7 -1
  2. package/lib/application.js.map +1 -1
  3. package/lib/core.d.ts +13 -0
  4. package/lib/core.js +58 -2
  5. package/lib/core.js.map +1 -1
  6. package/lib/core.spec.js +10 -4
  7. package/lib/core.spec.js.map +1 -1
  8. package/lib/index.d.ts +5 -4
  9. package/lib/index.js +5 -4
  10. package/lib/index.js.map +1 -1
  11. package/lib/models/aclmodel.d.ts +23 -10
  12. package/lib/models/aclmodel.js +31 -21
  13. package/lib/models/aclmodel.js.map +1 -1
  14. package/lib/models/aclmodel.spec.js +20 -6
  15. package/lib/models/aclmodel.spec.js.map +1 -1
  16. package/lib/models/coremodel.d.ts +106 -14
  17. package/lib/models/coremodel.js +240 -42
  18. package/lib/models/coremodel.js.map +1 -1
  19. package/lib/models/coremodel.spec.js +21 -4
  20. package/lib/models/coremodel.spec.js.map +1 -1
  21. package/lib/models/ident.d.ts +2 -6
  22. package/lib/models/ident.js.map +1 -1
  23. package/lib/models/ident.spec.js.map +1 -1
  24. package/lib/models/ownermodel.js +1 -1
  25. package/lib/models/ownermodel.js.map +1 -1
  26. package/lib/models/relations.d.ts +20 -20
  27. package/lib/models/relations.js +31 -11
  28. package/lib/models/relations.js.map +1 -1
  29. package/lib/models/relations.spec.d.ts +11 -0
  30. package/lib/models/relations.spec.js +115 -0
  31. package/lib/models/relations.spec.js.map +1 -0
  32. package/lib/models/user.d.ts +2 -2
  33. package/lib/models/user.js.map +1 -1
  34. package/lib/services/asyncevents.d.ts +4 -3
  35. package/lib/services/asyncevents.js +17 -4
  36. package/lib/services/asyncevents.js.map +1 -1
  37. package/lib/services/authentication.js +1 -1
  38. package/lib/services/authentication.js.map +1 -1
  39. package/lib/services/binary.d.ts +26 -2
  40. package/lib/services/binary.js +160 -63
  41. package/lib/services/binary.js.map +1 -1
  42. package/lib/services/binary.spec.js +3 -1
  43. package/lib/services/binary.spec.js.map +1 -1
  44. package/lib/services/cloudbinary.d.ts +0 -18
  45. package/lib/services/cloudbinary.js +0 -94
  46. package/lib/services/cloudbinary.js.map +1 -1
  47. package/lib/services/cloudbinary.spec.js +18 -11
  48. package/lib/services/cloudbinary.spec.js.map +1 -1
  49. package/lib/services/configuration.d.ts +1 -1
  50. package/lib/services/configuration.js +2 -1
  51. package/lib/services/configuration.js.map +1 -1
  52. package/lib/services/domainservice.d.ts +2 -1
  53. package/lib/services/domainservice.js +16 -25
  54. package/lib/services/domainservice.js.map +1 -1
  55. package/lib/services/filebinary.js +1 -1
  56. package/lib/services/filebinary.js.map +1 -1
  57. package/lib/services/filebinary.spec.d.ts +1 -0
  58. package/lib/services/filebinary.spec.js +24 -2
  59. package/lib/services/filebinary.spec.js.map +1 -1
  60. package/lib/services/invitationservice.js +1 -1
  61. package/lib/services/invitationservice.js.map +1 -1
  62. package/lib/services/invitationservice.spec.js +3 -1
  63. package/lib/services/invitationservice.spec.js.map +1 -1
  64. package/lib/services/service.d.ts +4 -5
  65. package/lib/services/service.js +9 -34
  66. package/lib/services/service.js.map +1 -1
  67. package/lib/services/service.spec.js +2 -2
  68. package/lib/services/service.spec.js.map +1 -1
  69. package/lib/stores/aliasstore.js +5 -1
  70. package/lib/stores/aliasstore.js.map +1 -1
  71. package/lib/stores/file.js.map +1 -1
  72. package/lib/stores/file.spec.js +1 -1
  73. package/lib/stores/file.spec.js.map +1 -1
  74. package/lib/stores/mapper.d.ts +4 -4
  75. package/lib/stores/mapper.spec.js +1 -1
  76. package/lib/stores/mapper.spec.js.map +1 -1
  77. package/lib/stores/memory.d.ts +4 -0
  78. package/lib/stores/memory.js +8 -0
  79. package/lib/stores/memory.js.map +1 -1
  80. package/lib/stores/memory.spec.d.ts +1 -0
  81. package/lib/stores/memory.spec.js +34 -3
  82. package/lib/stores/memory.spec.js.map +1 -1
  83. package/lib/stores/modelmapper.d.ts +21 -0
  84. package/lib/stores/modelmapper.js +127 -0
  85. package/lib/stores/modelmapper.js.map +1 -0
  86. package/lib/stores/store.d.ts +27 -9
  87. package/lib/stores/store.js +136 -82
  88. package/lib/stores/store.js.map +1 -1
  89. package/lib/stores/store.spec.js +2 -2
  90. package/lib/stores/store.spec.js.map +1 -1
  91. package/lib/test.js +1 -1
  92. package/lib/test.js.map +1 -1
  93. package/lib/utils/case.d.ts +7 -0
  94. package/lib/utils/case.js +43 -0
  95. package/lib/utils/case.js.map +1 -0
  96. package/lib/utils/case.spec.d.ts +1 -0
  97. package/lib/utils/case.spec.js +50 -0
  98. package/lib/utils/case.spec.js.map +1 -0
  99. package/lib/utils/context.d.ts +15 -2
  100. package/lib/utils/context.js +24 -5
  101. package/lib/utils/context.js.map +1 -1
  102. package/lib/utils/cookie.spec.js +2 -2
  103. package/lib/utils/cookie.spec.js.map +1 -1
  104. package/lib/utils/esm.d.ts +9 -0
  105. package/lib/utils/esm.js +9 -0
  106. package/lib/utils/esm.js.map +1 -1
  107. package/lib/utils/logger.spec.js +5 -2
  108. package/lib/utils/logger.spec.js.map +1 -1
  109. package/lib/utils/serializers.js +8 -1
  110. package/lib/utils/serializers.js.map +1 -1
  111. package/lib/utils/serializers.spec.js +6 -0
  112. package/lib/utils/serializers.spec.js.map +1 -1
  113. package/lib/utils/session.spec.js +1 -1
  114. package/lib/utils/session.spec.js.map +1 -1
  115. package/lib/utils/throttler.d.ts +22 -2
  116. package/lib/utils/throttler.js +35 -3
  117. package/lib/utils/throttler.js.map +1 -1
  118. package/lib/utils/throttler.spec.js +10 -2
  119. package/lib/utils/throttler.spec.js.map +1 -1
  120. package/package.json +10 -10
  121. package/webda.module.json +60 -26
  122. package/test/data/binaries/123/Test_plop_456 +0 -0
  123. package/test/data/binaries/123/data +0 -1
  124. package/test/data/tasks/068e6a96-9fdc-44e2-80fa-d27ed28f5440.json +0 -1
  125. package/test/data/tasks/task_no_owner.json +0 -1
  126. package/test/data/tasks/task_public.json +0 -1
  127. package/test/data/tasks/task_user1.json +0 -1
  128. package/test/data/tasks/task_user2.json +0 -1
  129. package/test/my-cnf.json +0 -11
@@ -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, FilterKeys } from "../models/coremodel.js";
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 FilterKeys<T, number>>(uid: string, info: {
605
+ incrementAttributes<FK extends FilterAttributes<T, number>>(uid: string, info: {
598
606
  property: FK;
599
607
  value: number;
600
- }[]): Promise<any[]>;
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 FilterKeys<T, number>>(uid: string, prop: FK, value: number): Promise<any[]>;
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 FilterKeys<T, Array<any>>>(uid: string, prop: FK, item: any, index?: number, itemWriteCondition?: any, itemWriteConditionField?: string): Promise<void>;
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 FilterKeys<T, Array<any>>>(uid: string, prop: FK, index: number, itemWriteCondition: any, itemWriteConditionField?: string): Promise<void>;
637
+ deleteItemFromCollection<FK extends FilterAttributes<T, Array<any>>>(uid: string, prop: FK, index: number, itemWriteCondition: any, itemWriteConditionField?: string): Promise<Date>;
630
638
  /**
631
- * Get all results without pagination
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 FilterKeys<T, Array<any>>, CK extends keyof T>(model: T, collection: FK, conditionField?: CK, condition?: any, index?: number): void;
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 FilterKeys<T, Array<any>>>(model: T, prop: FK, item: any, updateDate: Date, index?: number, itemWriteCondition?: any, itemWriteConditionField?: string): Promise<void>;
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
  *
@@ -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] && !this._model["_" + name]) {
310
- throw Error("Action static method /_?" + name + "/ does not exist");
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] && !this._model.prototype["_" + name]) {
318
- throw Error("Action method /_?" + name + "/ does not exist");
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
- if (object instanceof CoreModel) {
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(this._model, object);
405
+ object = this._model.factory(object);
395
406
  }
396
407
  }
397
408
  else {
398
- object = this._model.factory(this._model, object);
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
- return this.emitSync("Store.PartialUpdated", {
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
- * Get all results without pagination
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 queryAll(query, context) {
540
- const res = [];
553
+ async *iterate(query = "", context) {
541
554
  if (query.includes("OFFSET")) {
542
- throw new Error("Cannot contain an OFFSET for queryAll method");
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
- object._creationDate ?? (object._creationDate = new Date());
722
- object._lastUpdate = new Date();
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
- await this.emitSync("Store.Save", {
764
+ // Handle object auto listener
765
+ const evt = {
729
766
  object: object,
730
767
  store: this,
731
768
  context: ctx
732
- });
733
- // Handle object auto listener
734
- await object._onSave();
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
- await this.emitSync("Store.Saved", {
779
+ const evtSaved = {
740
780
  object: object,
741
781
  store: this,
742
782
  context: ctx
743
- });
744
- await object._onSaved();
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
- if (partial) {
876
- await this.emitSync(`Store.PatchUpdate`, {
877
- object: loaded,
878
- store: this,
879
- update: object
880
- });
881
- }
882
- else {
883
- await this.emitSync(`Store.Update`, {
884
- object: loaded,
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
- if (partial) {
920
- await this.emitSync(`Store.PatchUpdated`, {
921
- object: saved,
922
- store: this
923
- });
924
- }
925
- else {
926
- await this.emitSync(`Store.Updated`, {
927
- object: saved,
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
- // Send preevent
1137
- await this.emitSync("Store.Delete", {
1171
+ const evt = {
1138
1172
  object: to_delete,
1139
1173
  store: this
1140
- });
1141
- await to_delete._onDelete();
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
- await this.emitSync("Store.Deleted", {
1198
+ const evtDeleted = {
1160
1199
  object: to_delete,
1161
1200
  store: this
1162
- });
1163
- await to_delete._onDeleted();
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
- await this.emitSync("Store.Get", {
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(modelPrototype, body, ctx);
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
- await this.emitSync("Store.WebCreate", {
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
- await this.emitSync("Store.Action", {
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
- await this.emitSync("Store.Actioned", {
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
- await this.emitSync("Store.Action", {
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
- await this.emitSync("Store.Actioned", {
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
- await this.emitSync("Store.WebUpdate", {
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
- await this.emitSync("Store.WebGet", {
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
- await this.emitSync("Store.WebDelete", {
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