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

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 (31) hide show
  1. package/dist/browser/index.js +14 -14
  2. package/dist/browser/index.js.map +7 -7
  3. package/dist/node/index.cjs +150 -41
  4. package/dist/node/index.cjs.map +7 -7
  5. package/dist/node/index.js +150 -41
  6. package/dist/node/index.js.map +7 -7
  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/event-types.d.ts +10 -1
  10. package/dist/ts/domain/events/event-types.d.ts.map +1 -1
  11. package/dist/ts/domain/interfaces/repository.d.ts +26 -0
  12. package/dist/ts/domain/interfaces/repository.d.ts.map +1 -1
  13. package/dist/ts/domain/services/model-service.d.ts +19 -1
  14. package/dist/ts/domain/services/model-service.d.ts.map +1 -1
  15. package/dist/ts/domain/services/read-only-model-service.d.ts +19 -0
  16. package/dist/ts/domain/services/read-only-model-service.d.ts.map +1 -1
  17. package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts +21 -3
  18. package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts.map +1 -1
  19. package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts +2 -0
  20. package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts.map +1 -0
  21. package/package.json +5 -5
  22. package/src/application/model-controller.test.ts +191 -0
  23. package/src/application/model-controller.ts +44 -1
  24. package/src/domain/events/event-types.ts +9 -0
  25. package/src/domain/interfaces/repository.ts +29 -0
  26. package/src/domain/services/model-service.test.ts +307 -0
  27. package/src/domain/services/model-service.ts +88 -1
  28. package/src/domain/services/read-only-model-service.test.ts +396 -0
  29. package/src/domain/services/read-only-model-service.ts +23 -3
  30. package/src/test/mock/repositories/mock-memory-repository.trash.test.ts +736 -0
  31. 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,6 +274,15 @@ 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 {
@@ -12680,7 +12705,7 @@ class ReadOnlyModelService extends BaseModelService {
12680
12705
  async load(lookup, options) {
12681
12706
  const beforeLoadEvent = new QueryEvent(this.getDescriptor("beforeLoad" /* BeforeLoad */, options?.scope), lookup);
12682
12707
  await this.emitter.emitAsync(beforeLoadEvent);
12683
- const details = await this.repository.load(lookup);
12708
+ const details = await this.repository.load(lookup, options);
12684
12709
  const afterLoadEvent = new QueryEvent(this.getDescriptor("afterLoad" /* AfterLoad */, options?.scope), lookup).setResult(details);
12685
12710
  await this.emitter.emitAsync(afterLoadEvent);
12686
12711
  return await this.normalizeDetail(details);
@@ -12688,7 +12713,7 @@ class ReadOnlyModelService extends BaseModelService {
12688
12713
  async loadMany(lookups, options) {
12689
12714
  const beforeLoadManyEvent = new QueryEvent(this.getDescriptor("beforeLoadMany" /* BeforeLoadMany */, options?.scope), lookups);
12690
12715
  await this.emitter.emitAsync(beforeLoadManyEvent);
12691
- const details = await this.repository.loadMany(lookups);
12716
+ const details = await this.repository.loadMany(lookups, options);
12692
12717
  const afterLoadManyEvent = new QueryEvent(this.getDescriptor("afterLoadMany" /* AfterLoadMany */, options?.scope), lookups).setResult(details);
12693
12718
  await this.emitter.emitAsync(afterLoadManyEvent);
12694
12719
  return await Promise.all(details.map((detail) => this.normalizeDetail(detail)));
@@ -12860,6 +12885,30 @@ class ModelService extends ReadOnlyModelService {
12860
12885
  await Promise.all(afterEvents.map((event) => this.emitter.emitAsync(event)));
12861
12886
  return await Promise.all(results.map((result) => this.normalizeDetail(result)));
12862
12887
  }
12888
+ async emptyTrash(filters) {
12889
+ const beforeEmptyTrashEvent = new MutationEvent(this.getDescriptor("beforeEmptyTrash" /* BeforeEmptyTrash */), filters);
12890
+ await this.emitter.emitAsync(beforeEmptyTrashEvent);
12891
+ const count = await this.repository.emptyTrash(filters);
12892
+ const afterEmptyTrashEvent = new MutationEvent(this.getDescriptor("afterEmptyTrash" /* AfterEmptyTrash */), filters).setResult(count);
12893
+ await this.emitter.emitAsync(afterEmptyTrashEvent);
12894
+ return count;
12895
+ }
12896
+ async permanentlyDeleteFromTrash(lookup) {
12897
+ const beforePermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDeleteFromTrash" /* BeforePermanentlyDeleteFromTrash */), lookup);
12898
+ await this.emitter.emitAsync(beforePermanentlyDeleteFromTrashEvent);
12899
+ const result = await this.repository.permanentlyDeleteFromTrash(lookup);
12900
+ const afterPermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDeleteFromTrash" /* AfterPermanentlyDeleteFromTrash */), lookup).setResult(result);
12901
+ await this.emitter.emitAsync(afterPermanentlyDeleteFromTrashEvent);
12902
+ return await this.normalizeSummary(result);
12903
+ }
12904
+ async permanentlyDelete(lookup) {
12905
+ const beforePermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDelete" /* BeforePermanentlyDelete */), lookup);
12906
+ await this.emitter.emitAsync(beforePermanentlyDeleteEvent);
12907
+ const result = await this.repository.permanentlyDelete(lookup);
12908
+ const afterPermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDelete" /* AfterPermanentlyDelete */), lookup).setResult(result);
12909
+ await this.emitter.emitAsync(afterPermanentlyDeleteEvent);
12910
+ return await this.normalizeSummary(result);
12911
+ }
12863
12912
  }
12864
12913
  // src/test/mock/models/mock-book-models.ts
12865
12914
  var import_core11 = require("@declaro/core");
@@ -12909,15 +12958,39 @@ class MockMemoryRepository {
12909
12958
  throw new Error("Primary key must be specified for MockMemoryRepository");
12910
12959
  }
12911
12960
  }
12912
- async load(input) {
12961
+ findOne(lookup, map2) {
12962
+ if (typeof this.args.lookup === "function") {
12963
+ return Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
12964
+ } else {
12965
+ return map2.get(lookup[this.entityMetadata.primaryKey]);
12966
+ }
12967
+ }
12968
+ findOneWithKey(lookup, map2) {
12969
+ if (typeof this.args.lookup === "function") {
12970
+ const item = Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
12971
+ if (item) {
12972
+ return { item, key: item[this.entityMetadata.primaryKey] };
12973
+ }
12974
+ } else {
12975
+ const key = lookup[this.entityMetadata.primaryKey];
12976
+ const item = map2.get(key);
12977
+ if (item) {
12978
+ return { item, key };
12979
+ }
12980
+ }
12981
+ return;
12982
+ }
12983
+ async load(input, options = {}) {
12913
12984
  if (!this.entityMetadata?.primaryKey) {
12914
12985
  throw new Error("Primary key is not defined in the schema metadata");
12915
12986
  }
12916
12987
  let item;
12917
- if (typeof this.args.lookup === "function") {
12918
- item = Array.from(this.data.values()).find((data) => this.args.lookup(data, input));
12988
+ if (options.removedOnly) {
12989
+ item = this.findOne(input, this.trash);
12990
+ } else if (options.includeRemoved) {
12991
+ item = this.findOne(input, this.data) ?? this.findOne(input, this.trash);
12919
12992
  } else {
12920
- item = await this.data.get(input[this.entityMetadata.primaryKey]);
12993
+ item = this.findOne(input, this.data);
12921
12994
  }
12922
12995
  return item || null;
12923
12996
  }
@@ -12941,7 +13014,7 @@ class MockMemoryRepository {
12941
13014
  }
12942
13015
  async search(input, options) {
12943
13016
  const pagination = options?.pagination || { page: 1, pageSize: 25 };
12944
- let items = this.applyFilters(input);
13017
+ let items = this.applyFilters(input, options);
12945
13018
  if (options?.sort && Array.isArray(options.sort)) {
12946
13019
  items = items.sort((a, b) => {
12947
13020
  for (const sortField of options.sort) {
@@ -12979,45 +13052,25 @@ class MockMemoryRepository {
12979
13052
  if (!this.entityMetadata?.primaryKey) {
12980
13053
  throw new Error("Primary key is not defined in the schema metadata");
12981
13054
  }
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) {
13055
+ const found = this.findOneWithKey(lookup, this.data);
13056
+ if (!found) {
12994
13057
  throw new Error("Item not found");
12995
13058
  }
12996
- this.trash.set(itemKey, item);
12997
- this.data.delete(itemKey);
12998
- return item;
13059
+ this.trash.set(found.key, found.item);
13060
+ this.data.delete(found.key);
13061
+ return found.item;
12999
13062
  }
13000
13063
  async restore(lookup) {
13001
13064
  if (!this.entityMetadata?.primaryKey) {
13002
13065
  throw new Error("Primary key is not defined in the schema metadata");
13003
13066
  }
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) {
13067
+ const found = this.findOneWithKey(lookup, this.trash);
13068
+ if (!found) {
13016
13069
  throw new Error("Item not found in trash");
13017
13070
  }
13018
- this.trash.delete(itemKey);
13019
- this.data.set(itemKey, item);
13020
- return item;
13071
+ this.trash.delete(found.key);
13072
+ this.data.set(found.key, found.item);
13073
+ return found.item;
13021
13074
  }
13022
13075
  async create(input) {
13023
13076
  if (!this.entityMetadata?.primaryKey) {
@@ -13063,7 +13116,7 @@ class MockMemoryRepository {
13063
13116
  return updatedItem;
13064
13117
  }
13065
13118
  async count(search, options) {
13066
- const filteredItems = this.applyFilters(search);
13119
+ const filteredItems = this.applyFilters(search, options);
13067
13120
  return filteredItems.length;
13068
13121
  }
13069
13122
  async upsert(input, options) {
@@ -13082,8 +13135,64 @@ class MockMemoryRepository {
13082
13135
  async bulkUpsert(inputs, options) {
13083
13136
  return await Promise.all(inputs.map((input) => this.upsert(input, options)));
13084
13137
  }
13085
- applyFilters(input) {
13086
- return Array.from(this.data.values()).filter((item) => {
13138
+ async permanentlyDelete(lookup) {
13139
+ if (!this.entityMetadata?.primaryKey) {
13140
+ throw new Error("Primary key is not defined in the schema metadata");
13141
+ }
13142
+ const foundInData = this.findOneWithKey(lookup, this.data);
13143
+ if (foundInData) {
13144
+ this.data.delete(foundInData.key);
13145
+ return foundInData.item;
13146
+ }
13147
+ const foundInTrash = this.findOneWithKey(lookup, this.trash);
13148
+ if (foundInTrash) {
13149
+ this.trash.delete(foundInTrash.key);
13150
+ return foundInTrash.item;
13151
+ }
13152
+ throw new Error("Item not found");
13153
+ }
13154
+ async permanentlyDeleteFromTrash(lookup) {
13155
+ if (!this.entityMetadata?.primaryKey) {
13156
+ throw new Error("Primary key is not defined in the schema metadata");
13157
+ }
13158
+ const found = this.findOneWithKey(lookup, this.trash);
13159
+ if (!found) {
13160
+ throw new Error("Item not found in trash");
13161
+ }
13162
+ this.trash.delete(found.key);
13163
+ return found.item;
13164
+ }
13165
+ async emptyTrash(filters) {
13166
+ if (!filters || Object.keys(filters).length === 0) {
13167
+ const count = this.trash.size;
13168
+ this.trash.clear();
13169
+ return count;
13170
+ }
13171
+ const itemsToDelete = [];
13172
+ for (const [key, item] of this.trash.entries()) {
13173
+ if (typeof this.args.filter === "function") {
13174
+ if (this.args.filter(item, filters)) {
13175
+ itemsToDelete.push(key);
13176
+ }
13177
+ } else {
13178
+ itemsToDelete.push(key);
13179
+ }
13180
+ }
13181
+ for (const key of itemsToDelete) {
13182
+ this.trash.delete(key);
13183
+ }
13184
+ return itemsToDelete.length;
13185
+ }
13186
+ applyFilters(input, options) {
13187
+ let sourceItems;
13188
+ if (options?.removedOnly) {
13189
+ sourceItems = Array.from(this.trash.values());
13190
+ } else if (options?.includeRemoved) {
13191
+ sourceItems = [...Array.from(this.data.values()), ...Array.from(this.trash.values())];
13192
+ } else {
13193
+ sourceItems = Array.from(this.data.values());
13194
+ }
13195
+ return sourceItems.filter((item) => {
13087
13196
  if (typeof this.args.filter === "function") {
13088
13197
  return this.args.filter(item, input);
13089
13198
  } else {
@@ -13113,5 +13222,5 @@ class MockMemoryRepository {
13113
13222
  }
13114
13223
  }
13115
13224
 
13116
- //# debugId=CDABACEBE68C85EA64756E2164756E21
13225
+ //# debugId=DC46120685DB9C9464756E2164756E21
13117
13226
  //# sourceMappingURL=index.cjs.map