@declaro/data 2.0.0-beta.120 → 2.0.0-beta.125

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 (47) hide show
  1. package/dist/browser/index.js +14 -14
  2. package/dist/browser/index.js.map +11 -11
  3. package/dist/node/index.cjs +163 -45
  4. package/dist/node/index.cjs.map +11 -11
  5. package/dist/node/index.js +163 -45
  6. package/dist/node/index.js.map +11 -11
  7. package/dist/ts/application/model-controller.d.ts +22 -1
  8. package/dist/ts/application/model-controller.d.ts.map +1 -1
  9. package/dist/ts/domain/events/domain-event.d.ts +1 -1
  10. package/dist/ts/domain/events/domain-event.d.ts.map +1 -1
  11. package/dist/ts/domain/events/event-types.d.ts +10 -1
  12. package/dist/ts/domain/events/event-types.d.ts.map +1 -1
  13. package/dist/ts/domain/events/mutation-event.d.ts +5 -2
  14. package/dist/ts/domain/events/mutation-event.d.ts.map +1 -1
  15. package/dist/ts/domain/events/query-event.d.ts +4 -2
  16. package/dist/ts/domain/events/query-event.d.ts.map +1 -1
  17. package/dist/ts/domain/events/request-event.d.ts +17 -2
  18. package/dist/ts/domain/events/request-event.d.ts.map +1 -1
  19. package/dist/ts/domain/interfaces/repository.d.ts +26 -0
  20. package/dist/ts/domain/interfaces/repository.d.ts.map +1 -1
  21. package/dist/ts/domain/services/model-service.d.ts +19 -1
  22. package/dist/ts/domain/services/model-service.d.ts.map +1 -1
  23. package/dist/ts/domain/services/read-only-model-service.d.ts +19 -0
  24. package/dist/ts/domain/services/read-only-model-service.d.ts.map +1 -1
  25. package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts +21 -3
  26. package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts.map +1 -1
  27. package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts +2 -0
  28. package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts.map +1 -0
  29. package/package.json +5 -5
  30. package/src/application/model-controller.test.ts +191 -0
  31. package/src/application/model-controller.ts +44 -1
  32. package/src/domain/events/domain-event.ts +1 -1
  33. package/src/domain/events/event-types.ts +9 -0
  34. package/src/domain/events/mutation-event.test.ts +369 -17
  35. package/src/domain/events/mutation-event.ts +10 -2
  36. package/src/domain/events/query-event.test.ts +218 -18
  37. package/src/domain/events/query-event.ts +8 -2
  38. package/src/domain/events/request-event.test.ts +1 -1
  39. package/src/domain/events/request-event.ts +22 -7
  40. package/src/domain/interfaces/repository.ts +29 -0
  41. package/src/domain/services/model-service.normalization.test.ts +6 -6
  42. package/src/domain/services/model-service.test.ts +311 -7
  43. package/src/domain/services/model-service.ts +88 -1
  44. package/src/domain/services/read-only-model-service.test.ts +396 -0
  45. package/src/domain/services/read-only-model-service.ts +23 -3
  46. package/src/test/mock/repositories/mock-memory-repository.trash.test.ts +736 -0
  47. package/src/test/mock/repositories/mock-memory-repository.ts +146 -46
@@ -144,6 +144,22 @@ class ModelController extends ReadOnlyModelController {
144
144
  this.authValidator.validatePermissions((v) => v.someOf([createAndUpdateValidator, this.service.getDescriptor("write", "*").toString()]));
145
145
  return this.service.bulkUpsert(inputs, options);
146
146
  }
147
+ async permanentlyDeleteFromTrash(lookup) {
148
+ this.authValidator.validatePermissions((v) => v.someOf([
149
+ this.service.getDescriptor("permanently-delete-from-trash", "*").toString(),
150
+ this.service.getDescriptor("permanently-delete", "*").toString(),
151
+ this.service.getDescriptor("empty-trash", "*").toString()
152
+ ]));
153
+ return this.service.permanentlyDeleteFromTrash(lookup);
154
+ }
155
+ async permanentlyDelete(lookup) {
156
+ this.authValidator.validatePermissions((v) => v.someOf([this.service.getDescriptor("permanently-delete", "*").toString()]));
157
+ return this.service.permanentlyDelete(lookup);
158
+ }
159
+ async emptyTrash(filters) {
160
+ this.authValidator.validatePermissions((v) => v.someOf([this.service.getDescriptor("empty-trash", "*").toString()]));
161
+ return this.service.emptyTrash(filters);
162
+ }
147
163
  }
148
164
  // src/domain/events/domain-event.ts
149
165
  var import_core2 = require("@declaro/core");
@@ -258,17 +274,29 @@ var ModelMutationAction;
258
274
  ModelMutationAction2["Restore"] = "restore";
259
275
  ModelMutationAction2["BeforeRestore"] = "beforeRestore";
260
276
  ModelMutationAction2["AfterRestore"] = "afterRestore";
277
+ ModelMutationAction2["EmptyTrash"] = "emptyTrash";
278
+ ModelMutationAction2["BeforeEmptyTrash"] = "beforeEmptyTrash";
279
+ ModelMutationAction2["AfterEmptyTrash"] = "afterEmptyTrash";
280
+ ModelMutationAction2["PermanentlyDeleteFromTrash"] = "permanentlyDeleteFromTrash";
281
+ ModelMutationAction2["BeforePermanentlyDeleteFromTrash"] = "beforePermanentlyDeleteFromTrash";
282
+ ModelMutationAction2["AfterPermanentlyDeleteFromTrash"] = "afterPermanentlyDeleteFromTrash";
283
+ ModelMutationAction2["PermanentlyDelete"] = "permanentlyDelete";
284
+ ModelMutationAction2["BeforePermanentlyDelete"] = "beforePermanentlyDelete";
285
+ ModelMutationAction2["AfterPermanentlyDelete"] = "afterPermanentlyDelete";
261
286
  })(ModelMutationAction ||= {});
262
287
  // src/domain/events/request-event.ts
263
288
  class RequestEvent extends DomainEvent {
289
+ input;
264
290
  constructor(descriptor, input, meta = {}) {
265
291
  super({
266
- meta: {
267
- ...meta,
268
- input
269
- },
292
+ meta,
270
293
  descriptor
271
294
  });
295
+ this.input = input;
296
+ }
297
+ setInput(input) {
298
+ this.input = input;
299
+ return this;
272
300
  }
273
301
  setMeta(meta) {
274
302
  this.meta = { ...this.meta, ...meta };
@@ -278,6 +306,12 @@ class RequestEvent extends DomainEvent {
278
306
  this.data = result;
279
307
  return this;
280
308
  }
309
+ toJSON() {
310
+ return {
311
+ ...super.toJSON(),
312
+ input: this.input
313
+ };
314
+ }
281
315
  }
282
316
 
283
317
  // src/domain/events/mutation-event.ts
@@ -12680,7 +12714,7 @@ class ReadOnlyModelService extends BaseModelService {
12680
12714
  async load(lookup, options) {
12681
12715
  const beforeLoadEvent = new QueryEvent(this.getDescriptor("beforeLoad" /* BeforeLoad */, options?.scope), lookup);
12682
12716
  await this.emitter.emitAsync(beforeLoadEvent);
12683
- const details = await this.repository.load(lookup);
12717
+ const details = await this.repository.load(lookup, options);
12684
12718
  const afterLoadEvent = new QueryEvent(this.getDescriptor("afterLoad" /* AfterLoad */, options?.scope), lookup).setResult(details);
12685
12719
  await this.emitter.emitAsync(afterLoadEvent);
12686
12720
  return await this.normalizeDetail(details);
@@ -12688,7 +12722,7 @@ class ReadOnlyModelService extends BaseModelService {
12688
12722
  async loadMany(lookups, options) {
12689
12723
  const beforeLoadManyEvent = new QueryEvent(this.getDescriptor("beforeLoadMany" /* BeforeLoadMany */, options?.scope), lookups);
12690
12724
  await this.emitter.emitAsync(beforeLoadManyEvent);
12691
- const details = await this.repository.loadMany(lookups);
12725
+ const details = await this.repository.loadMany(lookups, options);
12692
12726
  const afterLoadManyEvent = new QueryEvent(this.getDescriptor("afterLoadMany" /* AfterLoadMany */, options?.scope), lookups).setResult(details);
12693
12727
  await this.emitter.emitAsync(afterLoadManyEvent);
12694
12728
  return await Promise.all(details.map((detail) => this.normalizeDetail(detail)));
@@ -12860,6 +12894,30 @@ class ModelService extends ReadOnlyModelService {
12860
12894
  await Promise.all(afterEvents.map((event) => this.emitter.emitAsync(event)));
12861
12895
  return await Promise.all(results.map((result) => this.normalizeDetail(result)));
12862
12896
  }
12897
+ async emptyTrash(filters) {
12898
+ const beforeEmptyTrashEvent = new MutationEvent(this.getDescriptor("beforeEmptyTrash" /* BeforeEmptyTrash */), filters);
12899
+ await this.emitter.emitAsync(beforeEmptyTrashEvent);
12900
+ const count = await this.repository.emptyTrash(filters);
12901
+ const afterEmptyTrashEvent = new MutationEvent(this.getDescriptor("afterEmptyTrash" /* AfterEmptyTrash */), filters).setResult(count);
12902
+ await this.emitter.emitAsync(afterEmptyTrashEvent);
12903
+ return count;
12904
+ }
12905
+ async permanentlyDeleteFromTrash(lookup) {
12906
+ const beforePermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDeleteFromTrash" /* BeforePermanentlyDeleteFromTrash */), lookup);
12907
+ await this.emitter.emitAsync(beforePermanentlyDeleteFromTrashEvent);
12908
+ const result = await this.repository.permanentlyDeleteFromTrash(lookup);
12909
+ const afterPermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDeleteFromTrash" /* AfterPermanentlyDeleteFromTrash */), lookup).setResult(result);
12910
+ await this.emitter.emitAsync(afterPermanentlyDeleteFromTrashEvent);
12911
+ return await this.normalizeSummary(result);
12912
+ }
12913
+ async permanentlyDelete(lookup) {
12914
+ const beforePermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDelete" /* BeforePermanentlyDelete */), lookup);
12915
+ await this.emitter.emitAsync(beforePermanentlyDeleteEvent);
12916
+ const result = await this.repository.permanentlyDelete(lookup);
12917
+ const afterPermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDelete" /* AfterPermanentlyDelete */), lookup).setResult(result);
12918
+ await this.emitter.emitAsync(afterPermanentlyDeleteEvent);
12919
+ return await this.normalizeSummary(result);
12920
+ }
12863
12921
  }
12864
12922
  // src/test/mock/models/mock-book-models.ts
12865
12923
  var import_core11 = require("@declaro/core");
@@ -12909,15 +12967,39 @@ class MockMemoryRepository {
12909
12967
  throw new Error("Primary key must be specified for MockMemoryRepository");
12910
12968
  }
12911
12969
  }
12912
- async load(input) {
12970
+ findOne(lookup, map2) {
12971
+ if (typeof this.args.lookup === "function") {
12972
+ return Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
12973
+ } else {
12974
+ return map2.get(lookup[this.entityMetadata.primaryKey]);
12975
+ }
12976
+ }
12977
+ findOneWithKey(lookup, map2) {
12978
+ if (typeof this.args.lookup === "function") {
12979
+ const item = Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
12980
+ if (item) {
12981
+ return { item, key: item[this.entityMetadata.primaryKey] };
12982
+ }
12983
+ } else {
12984
+ const key = lookup[this.entityMetadata.primaryKey];
12985
+ const item = map2.get(key);
12986
+ if (item) {
12987
+ return { item, key };
12988
+ }
12989
+ }
12990
+ return;
12991
+ }
12992
+ async load(input, options = {}) {
12913
12993
  if (!this.entityMetadata?.primaryKey) {
12914
12994
  throw new Error("Primary key is not defined in the schema metadata");
12915
12995
  }
12916
12996
  let item;
12917
- if (typeof this.args.lookup === "function") {
12918
- item = Array.from(this.data.values()).find((data) => this.args.lookup(data, input));
12997
+ if (options.removedOnly) {
12998
+ item = this.findOne(input, this.trash);
12999
+ } else if (options.includeRemoved) {
13000
+ item = this.findOne(input, this.data) ?? this.findOne(input, this.trash);
12919
13001
  } else {
12920
- item = await this.data.get(input[this.entityMetadata.primaryKey]);
13002
+ item = this.findOne(input, this.data);
12921
13003
  }
12922
13004
  return item || null;
12923
13005
  }
@@ -12941,7 +13023,7 @@ class MockMemoryRepository {
12941
13023
  }
12942
13024
  async search(input, options) {
12943
13025
  const pagination = options?.pagination || { page: 1, pageSize: 25 };
12944
- let items = this.applyFilters(input);
13026
+ let items = this.applyFilters(input, options);
12945
13027
  if (options?.sort && Array.isArray(options.sort)) {
12946
13028
  items = items.sort((a, b) => {
12947
13029
  for (const sortField of options.sort) {
@@ -12979,45 +13061,25 @@ class MockMemoryRepository {
12979
13061
  if (!this.entityMetadata?.primaryKey) {
12980
13062
  throw new Error("Primary key is not defined in the schema metadata");
12981
13063
  }
12982
- let item;
12983
- let itemKey;
12984
- if (typeof this.args.lookup === "function") {
12985
- item = Array.from(this.data.values()).find((data) => this.args.lookup(data, lookup));
12986
- if (item) {
12987
- itemKey = item[this.entityMetadata.primaryKey];
12988
- }
12989
- } else {
12990
- itemKey = lookup[this.entityMetadata.primaryKey];
12991
- item = this.data.get(itemKey);
12992
- }
12993
- if (!item) {
13064
+ const found = this.findOneWithKey(lookup, this.data);
13065
+ if (!found) {
12994
13066
  throw new Error("Item not found");
12995
13067
  }
12996
- this.trash.set(itemKey, item);
12997
- this.data.delete(itemKey);
12998
- return item;
13068
+ this.trash.set(found.key, found.item);
13069
+ this.data.delete(found.key);
13070
+ return found.item;
12999
13071
  }
13000
13072
  async restore(lookup) {
13001
13073
  if (!this.entityMetadata?.primaryKey) {
13002
13074
  throw new Error("Primary key is not defined in the schema metadata");
13003
13075
  }
13004
- let item;
13005
- let itemKey;
13006
- if (typeof this.args.lookup === "function") {
13007
- item = Array.from(this.trash.values()).find((data) => this.args.lookup(data, lookup));
13008
- if (item) {
13009
- itemKey = item[this.entityMetadata.primaryKey];
13010
- }
13011
- } else {
13012
- itemKey = lookup[this.entityMetadata.primaryKey];
13013
- item = this.trash.get(itemKey);
13014
- }
13015
- if (!item) {
13076
+ const found = this.findOneWithKey(lookup, this.trash);
13077
+ if (!found) {
13016
13078
  throw new Error("Item not found in trash");
13017
13079
  }
13018
- this.trash.delete(itemKey);
13019
- this.data.set(itemKey, item);
13020
- return item;
13080
+ this.trash.delete(found.key);
13081
+ this.data.set(found.key, found.item);
13082
+ return found.item;
13021
13083
  }
13022
13084
  async create(input) {
13023
13085
  if (!this.entityMetadata?.primaryKey) {
@@ -13063,7 +13125,7 @@ class MockMemoryRepository {
13063
13125
  return updatedItem;
13064
13126
  }
13065
13127
  async count(search, options) {
13066
- const filteredItems = this.applyFilters(search);
13128
+ const filteredItems = this.applyFilters(search, options);
13067
13129
  return filteredItems.length;
13068
13130
  }
13069
13131
  async upsert(input, options) {
@@ -13082,8 +13144,64 @@ class MockMemoryRepository {
13082
13144
  async bulkUpsert(inputs, options) {
13083
13145
  return await Promise.all(inputs.map((input) => this.upsert(input, options)));
13084
13146
  }
13085
- applyFilters(input) {
13086
- return Array.from(this.data.values()).filter((item) => {
13147
+ async permanentlyDelete(lookup) {
13148
+ if (!this.entityMetadata?.primaryKey) {
13149
+ throw new Error("Primary key is not defined in the schema metadata");
13150
+ }
13151
+ const foundInData = this.findOneWithKey(lookup, this.data);
13152
+ if (foundInData) {
13153
+ this.data.delete(foundInData.key);
13154
+ return foundInData.item;
13155
+ }
13156
+ const foundInTrash = this.findOneWithKey(lookup, this.trash);
13157
+ if (foundInTrash) {
13158
+ this.trash.delete(foundInTrash.key);
13159
+ return foundInTrash.item;
13160
+ }
13161
+ throw new Error("Item not found");
13162
+ }
13163
+ async permanentlyDeleteFromTrash(lookup) {
13164
+ if (!this.entityMetadata?.primaryKey) {
13165
+ throw new Error("Primary key is not defined in the schema metadata");
13166
+ }
13167
+ const found = this.findOneWithKey(lookup, this.trash);
13168
+ if (!found) {
13169
+ throw new Error("Item not found in trash");
13170
+ }
13171
+ this.trash.delete(found.key);
13172
+ return found.item;
13173
+ }
13174
+ async emptyTrash(filters) {
13175
+ if (!filters || Object.keys(filters).length === 0) {
13176
+ const count = this.trash.size;
13177
+ this.trash.clear();
13178
+ return count;
13179
+ }
13180
+ const itemsToDelete = [];
13181
+ for (const [key, item] of this.trash.entries()) {
13182
+ if (typeof this.args.filter === "function") {
13183
+ if (this.args.filter(item, filters)) {
13184
+ itemsToDelete.push(key);
13185
+ }
13186
+ } else {
13187
+ itemsToDelete.push(key);
13188
+ }
13189
+ }
13190
+ for (const key of itemsToDelete) {
13191
+ this.trash.delete(key);
13192
+ }
13193
+ return itemsToDelete.length;
13194
+ }
13195
+ applyFilters(input, options) {
13196
+ let sourceItems;
13197
+ if (options?.removedOnly) {
13198
+ sourceItems = Array.from(this.trash.values());
13199
+ } else if (options?.includeRemoved) {
13200
+ sourceItems = [...Array.from(this.data.values()), ...Array.from(this.trash.values())];
13201
+ } else {
13202
+ sourceItems = Array.from(this.data.values());
13203
+ }
13204
+ return sourceItems.filter((item) => {
13087
13205
  if (typeof this.args.filter === "function") {
13088
13206
  return this.args.filter(item, input);
13089
13207
  } else {
@@ -13113,5 +13231,5 @@ class MockMemoryRepository {
13113
13231
  }
13114
13232
  }
13115
13233
 
13116
- //# debugId=CDABACEBE68C85EA64756E2164756E21
13234
+ //# debugId=E3CA467BBFBED82664756E2164756E21
13117
13235
  //# sourceMappingURL=index.cjs.map