@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.
- package/dist/browser/index.js +14 -14
- package/dist/browser/index.js.map +7 -7
- package/dist/node/index.cjs +150 -41
- package/dist/node/index.cjs.map +7 -7
- package/dist/node/index.js +150 -41
- package/dist/node/index.js.map +7 -7
- package/dist/ts/application/model-controller.d.ts +22 -1
- package/dist/ts/application/model-controller.d.ts.map +1 -1
- package/dist/ts/domain/events/event-types.d.ts +10 -1
- package/dist/ts/domain/events/event-types.d.ts.map +1 -1
- package/dist/ts/domain/interfaces/repository.d.ts +26 -0
- package/dist/ts/domain/interfaces/repository.d.ts.map +1 -1
- package/dist/ts/domain/services/model-service.d.ts +19 -1
- package/dist/ts/domain/services/model-service.d.ts.map +1 -1
- package/dist/ts/domain/services/read-only-model-service.d.ts +19 -0
- package/dist/ts/domain/services/read-only-model-service.d.ts.map +1 -1
- package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts +21 -3
- package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts.map +1 -1
- package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts +2 -0
- package/dist/ts/test/mock/repositories/mock-memory-repository.trash.test.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/application/model-controller.test.ts +191 -0
- package/src/application/model-controller.ts +44 -1
- package/src/domain/events/event-types.ts +9 -0
- package/src/domain/interfaces/repository.ts +29 -0
- package/src/domain/services/model-service.test.ts +307 -0
- package/src/domain/services/model-service.ts +88 -1
- package/src/domain/services/read-only-model-service.test.ts +396 -0
- package/src/domain/services/read-only-model-service.ts +23 -3
- package/src/test/mock/repositories/mock-memory-repository.trash.test.ts +736 -0
- package/src/test/mock/repositories/mock-memory-repository.ts +146 -46
package/dist/node/index.js
CHANGED
|
@@ -105,6 +105,22 @@ class ModelController extends ReadOnlyModelController {
|
|
|
105
105
|
this.authValidator.validatePermissions((v) => v.someOf([createAndUpdateValidator, this.service.getDescriptor("write", "*").toString()]));
|
|
106
106
|
return this.service.bulkUpsert(inputs, options);
|
|
107
107
|
}
|
|
108
|
+
async permanentlyDeleteFromTrash(lookup) {
|
|
109
|
+
this.authValidator.validatePermissions((v) => v.someOf([
|
|
110
|
+
this.service.getDescriptor("permanently-delete-from-trash", "*").toString(),
|
|
111
|
+
this.service.getDescriptor("permanently-delete", "*").toString(),
|
|
112
|
+
this.service.getDescriptor("empty-trash", "*").toString()
|
|
113
|
+
]));
|
|
114
|
+
return this.service.permanentlyDeleteFromTrash(lookup);
|
|
115
|
+
}
|
|
116
|
+
async permanentlyDelete(lookup) {
|
|
117
|
+
this.authValidator.validatePermissions((v) => v.someOf([this.service.getDescriptor("permanently-delete", "*").toString()]));
|
|
118
|
+
return this.service.permanentlyDelete(lookup);
|
|
119
|
+
}
|
|
120
|
+
async emptyTrash(filters) {
|
|
121
|
+
this.authValidator.validatePermissions((v) => v.someOf([this.service.getDescriptor("empty-trash", "*").toString()]));
|
|
122
|
+
return this.service.emptyTrash(filters);
|
|
123
|
+
}
|
|
108
124
|
}
|
|
109
125
|
// src/domain/events/domain-event.ts
|
|
110
126
|
import { ActionDescriptor } from "@declaro/core";
|
|
@@ -219,6 +235,15 @@ var ModelMutationAction;
|
|
|
219
235
|
ModelMutationAction2["Restore"] = "restore";
|
|
220
236
|
ModelMutationAction2["BeforeRestore"] = "beforeRestore";
|
|
221
237
|
ModelMutationAction2["AfterRestore"] = "afterRestore";
|
|
238
|
+
ModelMutationAction2["EmptyTrash"] = "emptyTrash";
|
|
239
|
+
ModelMutationAction2["BeforeEmptyTrash"] = "beforeEmptyTrash";
|
|
240
|
+
ModelMutationAction2["AfterEmptyTrash"] = "afterEmptyTrash";
|
|
241
|
+
ModelMutationAction2["PermanentlyDeleteFromTrash"] = "permanentlyDeleteFromTrash";
|
|
242
|
+
ModelMutationAction2["BeforePermanentlyDeleteFromTrash"] = "beforePermanentlyDeleteFromTrash";
|
|
243
|
+
ModelMutationAction2["AfterPermanentlyDeleteFromTrash"] = "afterPermanentlyDeleteFromTrash";
|
|
244
|
+
ModelMutationAction2["PermanentlyDelete"] = "permanentlyDelete";
|
|
245
|
+
ModelMutationAction2["BeforePermanentlyDelete"] = "beforePermanentlyDelete";
|
|
246
|
+
ModelMutationAction2["AfterPermanentlyDelete"] = "afterPermanentlyDelete";
|
|
222
247
|
})(ModelMutationAction ||= {});
|
|
223
248
|
// src/domain/events/request-event.ts
|
|
224
249
|
class RequestEvent extends DomainEvent {
|
|
@@ -12641,7 +12666,7 @@ class ReadOnlyModelService extends BaseModelService {
|
|
|
12641
12666
|
async load(lookup, options) {
|
|
12642
12667
|
const beforeLoadEvent = new QueryEvent(this.getDescriptor("beforeLoad" /* BeforeLoad */, options?.scope), lookup);
|
|
12643
12668
|
await this.emitter.emitAsync(beforeLoadEvent);
|
|
12644
|
-
const details = await this.repository.load(lookup);
|
|
12669
|
+
const details = await this.repository.load(lookup, options);
|
|
12645
12670
|
const afterLoadEvent = new QueryEvent(this.getDescriptor("afterLoad" /* AfterLoad */, options?.scope), lookup).setResult(details);
|
|
12646
12671
|
await this.emitter.emitAsync(afterLoadEvent);
|
|
12647
12672
|
return await this.normalizeDetail(details);
|
|
@@ -12649,7 +12674,7 @@ class ReadOnlyModelService extends BaseModelService {
|
|
|
12649
12674
|
async loadMany(lookups, options) {
|
|
12650
12675
|
const beforeLoadManyEvent = new QueryEvent(this.getDescriptor("beforeLoadMany" /* BeforeLoadMany */, options?.scope), lookups);
|
|
12651
12676
|
await this.emitter.emitAsync(beforeLoadManyEvent);
|
|
12652
|
-
const details = await this.repository.loadMany(lookups);
|
|
12677
|
+
const details = await this.repository.loadMany(lookups, options);
|
|
12653
12678
|
const afterLoadManyEvent = new QueryEvent(this.getDescriptor("afterLoadMany" /* AfterLoadMany */, options?.scope), lookups).setResult(details);
|
|
12654
12679
|
await this.emitter.emitAsync(afterLoadManyEvent);
|
|
12655
12680
|
return await Promise.all(details.map((detail) => this.normalizeDetail(detail)));
|
|
@@ -12821,6 +12846,30 @@ class ModelService extends ReadOnlyModelService {
|
|
|
12821
12846
|
await Promise.all(afterEvents.map((event) => this.emitter.emitAsync(event)));
|
|
12822
12847
|
return await Promise.all(results.map((result) => this.normalizeDetail(result)));
|
|
12823
12848
|
}
|
|
12849
|
+
async emptyTrash(filters) {
|
|
12850
|
+
const beforeEmptyTrashEvent = new MutationEvent(this.getDescriptor("beforeEmptyTrash" /* BeforeEmptyTrash */), filters);
|
|
12851
|
+
await this.emitter.emitAsync(beforeEmptyTrashEvent);
|
|
12852
|
+
const count = await this.repository.emptyTrash(filters);
|
|
12853
|
+
const afterEmptyTrashEvent = new MutationEvent(this.getDescriptor("afterEmptyTrash" /* AfterEmptyTrash */), filters).setResult(count);
|
|
12854
|
+
await this.emitter.emitAsync(afterEmptyTrashEvent);
|
|
12855
|
+
return count;
|
|
12856
|
+
}
|
|
12857
|
+
async permanentlyDeleteFromTrash(lookup) {
|
|
12858
|
+
const beforePermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDeleteFromTrash" /* BeforePermanentlyDeleteFromTrash */), lookup);
|
|
12859
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteFromTrashEvent);
|
|
12860
|
+
const result = await this.repository.permanentlyDeleteFromTrash(lookup);
|
|
12861
|
+
const afterPermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDeleteFromTrash" /* AfterPermanentlyDeleteFromTrash */), lookup).setResult(result);
|
|
12862
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteFromTrashEvent);
|
|
12863
|
+
return await this.normalizeSummary(result);
|
|
12864
|
+
}
|
|
12865
|
+
async permanentlyDelete(lookup) {
|
|
12866
|
+
const beforePermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDelete" /* BeforePermanentlyDelete */), lookup);
|
|
12867
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteEvent);
|
|
12868
|
+
const result = await this.repository.permanentlyDelete(lookup);
|
|
12869
|
+
const afterPermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDelete" /* AfterPermanentlyDelete */), lookup).setResult(result);
|
|
12870
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteEvent);
|
|
12871
|
+
return await this.normalizeSummary(result);
|
|
12872
|
+
}
|
|
12824
12873
|
}
|
|
12825
12874
|
// src/test/mock/models/mock-book-models.ts
|
|
12826
12875
|
import { ModelSchema as ModelSchema2 } from "@declaro/core";
|
|
@@ -12870,15 +12919,39 @@ class MockMemoryRepository {
|
|
|
12870
12919
|
throw new Error("Primary key must be specified for MockMemoryRepository");
|
|
12871
12920
|
}
|
|
12872
12921
|
}
|
|
12873
|
-
|
|
12922
|
+
findOne(lookup, map2) {
|
|
12923
|
+
if (typeof this.args.lookup === "function") {
|
|
12924
|
+
return Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
|
|
12925
|
+
} else {
|
|
12926
|
+
return map2.get(lookup[this.entityMetadata.primaryKey]);
|
|
12927
|
+
}
|
|
12928
|
+
}
|
|
12929
|
+
findOneWithKey(lookup, map2) {
|
|
12930
|
+
if (typeof this.args.lookup === "function") {
|
|
12931
|
+
const item = Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
|
|
12932
|
+
if (item) {
|
|
12933
|
+
return { item, key: item[this.entityMetadata.primaryKey] };
|
|
12934
|
+
}
|
|
12935
|
+
} else {
|
|
12936
|
+
const key = lookup[this.entityMetadata.primaryKey];
|
|
12937
|
+
const item = map2.get(key);
|
|
12938
|
+
if (item) {
|
|
12939
|
+
return { item, key };
|
|
12940
|
+
}
|
|
12941
|
+
}
|
|
12942
|
+
return;
|
|
12943
|
+
}
|
|
12944
|
+
async load(input, options = {}) {
|
|
12874
12945
|
if (!this.entityMetadata?.primaryKey) {
|
|
12875
12946
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12876
12947
|
}
|
|
12877
12948
|
let item;
|
|
12878
|
-
if (
|
|
12879
|
-
item =
|
|
12949
|
+
if (options.removedOnly) {
|
|
12950
|
+
item = this.findOne(input, this.trash);
|
|
12951
|
+
} else if (options.includeRemoved) {
|
|
12952
|
+
item = this.findOne(input, this.data) ?? this.findOne(input, this.trash);
|
|
12880
12953
|
} else {
|
|
12881
|
-
item =
|
|
12954
|
+
item = this.findOne(input, this.data);
|
|
12882
12955
|
}
|
|
12883
12956
|
return item || null;
|
|
12884
12957
|
}
|
|
@@ -12902,7 +12975,7 @@ class MockMemoryRepository {
|
|
|
12902
12975
|
}
|
|
12903
12976
|
async search(input, options) {
|
|
12904
12977
|
const pagination = options?.pagination || { page: 1, pageSize: 25 };
|
|
12905
|
-
let items = this.applyFilters(input);
|
|
12978
|
+
let items = this.applyFilters(input, options);
|
|
12906
12979
|
if (options?.sort && Array.isArray(options.sort)) {
|
|
12907
12980
|
items = items.sort((a, b) => {
|
|
12908
12981
|
for (const sortField of options.sort) {
|
|
@@ -12940,45 +13013,25 @@ class MockMemoryRepository {
|
|
|
12940
13013
|
if (!this.entityMetadata?.primaryKey) {
|
|
12941
13014
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12942
13015
|
}
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
if (typeof this.args.lookup === "function") {
|
|
12946
|
-
item = Array.from(this.data.values()).find((data) => this.args.lookup(data, lookup));
|
|
12947
|
-
if (item) {
|
|
12948
|
-
itemKey = item[this.entityMetadata.primaryKey];
|
|
12949
|
-
}
|
|
12950
|
-
} else {
|
|
12951
|
-
itemKey = lookup[this.entityMetadata.primaryKey];
|
|
12952
|
-
item = this.data.get(itemKey);
|
|
12953
|
-
}
|
|
12954
|
-
if (!item) {
|
|
13016
|
+
const found = this.findOneWithKey(lookup, this.data);
|
|
13017
|
+
if (!found) {
|
|
12955
13018
|
throw new Error("Item not found");
|
|
12956
13019
|
}
|
|
12957
|
-
this.trash.set(
|
|
12958
|
-
this.data.delete(
|
|
12959
|
-
return item;
|
|
13020
|
+
this.trash.set(found.key, found.item);
|
|
13021
|
+
this.data.delete(found.key);
|
|
13022
|
+
return found.item;
|
|
12960
13023
|
}
|
|
12961
13024
|
async restore(lookup) {
|
|
12962
13025
|
if (!this.entityMetadata?.primaryKey) {
|
|
12963
13026
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12964
13027
|
}
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
if (typeof this.args.lookup === "function") {
|
|
12968
|
-
item = Array.from(this.trash.values()).find((data) => this.args.lookup(data, lookup));
|
|
12969
|
-
if (item) {
|
|
12970
|
-
itemKey = item[this.entityMetadata.primaryKey];
|
|
12971
|
-
}
|
|
12972
|
-
} else {
|
|
12973
|
-
itemKey = lookup[this.entityMetadata.primaryKey];
|
|
12974
|
-
item = this.trash.get(itemKey);
|
|
12975
|
-
}
|
|
12976
|
-
if (!item) {
|
|
13028
|
+
const found = this.findOneWithKey(lookup, this.trash);
|
|
13029
|
+
if (!found) {
|
|
12977
13030
|
throw new Error("Item not found in trash");
|
|
12978
13031
|
}
|
|
12979
|
-
this.trash.delete(
|
|
12980
|
-
this.data.set(
|
|
12981
|
-
return item;
|
|
13032
|
+
this.trash.delete(found.key);
|
|
13033
|
+
this.data.set(found.key, found.item);
|
|
13034
|
+
return found.item;
|
|
12982
13035
|
}
|
|
12983
13036
|
async create(input) {
|
|
12984
13037
|
if (!this.entityMetadata?.primaryKey) {
|
|
@@ -13024,7 +13077,7 @@ class MockMemoryRepository {
|
|
|
13024
13077
|
return updatedItem;
|
|
13025
13078
|
}
|
|
13026
13079
|
async count(search, options) {
|
|
13027
|
-
const filteredItems = this.applyFilters(search);
|
|
13080
|
+
const filteredItems = this.applyFilters(search, options);
|
|
13028
13081
|
return filteredItems.length;
|
|
13029
13082
|
}
|
|
13030
13083
|
async upsert(input, options) {
|
|
@@ -13043,8 +13096,64 @@ class MockMemoryRepository {
|
|
|
13043
13096
|
async bulkUpsert(inputs, options) {
|
|
13044
13097
|
return await Promise.all(inputs.map((input) => this.upsert(input, options)));
|
|
13045
13098
|
}
|
|
13046
|
-
|
|
13047
|
-
|
|
13099
|
+
async permanentlyDelete(lookup) {
|
|
13100
|
+
if (!this.entityMetadata?.primaryKey) {
|
|
13101
|
+
throw new Error("Primary key is not defined in the schema metadata");
|
|
13102
|
+
}
|
|
13103
|
+
const foundInData = this.findOneWithKey(lookup, this.data);
|
|
13104
|
+
if (foundInData) {
|
|
13105
|
+
this.data.delete(foundInData.key);
|
|
13106
|
+
return foundInData.item;
|
|
13107
|
+
}
|
|
13108
|
+
const foundInTrash = this.findOneWithKey(lookup, this.trash);
|
|
13109
|
+
if (foundInTrash) {
|
|
13110
|
+
this.trash.delete(foundInTrash.key);
|
|
13111
|
+
return foundInTrash.item;
|
|
13112
|
+
}
|
|
13113
|
+
throw new Error("Item not found");
|
|
13114
|
+
}
|
|
13115
|
+
async permanentlyDeleteFromTrash(lookup) {
|
|
13116
|
+
if (!this.entityMetadata?.primaryKey) {
|
|
13117
|
+
throw new Error("Primary key is not defined in the schema metadata");
|
|
13118
|
+
}
|
|
13119
|
+
const found = this.findOneWithKey(lookup, this.trash);
|
|
13120
|
+
if (!found) {
|
|
13121
|
+
throw new Error("Item not found in trash");
|
|
13122
|
+
}
|
|
13123
|
+
this.trash.delete(found.key);
|
|
13124
|
+
return found.item;
|
|
13125
|
+
}
|
|
13126
|
+
async emptyTrash(filters) {
|
|
13127
|
+
if (!filters || Object.keys(filters).length === 0) {
|
|
13128
|
+
const count = this.trash.size;
|
|
13129
|
+
this.trash.clear();
|
|
13130
|
+
return count;
|
|
13131
|
+
}
|
|
13132
|
+
const itemsToDelete = [];
|
|
13133
|
+
for (const [key, item] of this.trash.entries()) {
|
|
13134
|
+
if (typeof this.args.filter === "function") {
|
|
13135
|
+
if (this.args.filter(item, filters)) {
|
|
13136
|
+
itemsToDelete.push(key);
|
|
13137
|
+
}
|
|
13138
|
+
} else {
|
|
13139
|
+
itemsToDelete.push(key);
|
|
13140
|
+
}
|
|
13141
|
+
}
|
|
13142
|
+
for (const key of itemsToDelete) {
|
|
13143
|
+
this.trash.delete(key);
|
|
13144
|
+
}
|
|
13145
|
+
return itemsToDelete.length;
|
|
13146
|
+
}
|
|
13147
|
+
applyFilters(input, options) {
|
|
13148
|
+
let sourceItems;
|
|
13149
|
+
if (options?.removedOnly) {
|
|
13150
|
+
sourceItems = Array.from(this.trash.values());
|
|
13151
|
+
} else if (options?.includeRemoved) {
|
|
13152
|
+
sourceItems = [...Array.from(this.data.values()), ...Array.from(this.trash.values())];
|
|
13153
|
+
} else {
|
|
13154
|
+
sourceItems = Array.from(this.data.values());
|
|
13155
|
+
}
|
|
13156
|
+
return sourceItems.filter((item) => {
|
|
13048
13157
|
if (typeof this.args.filter === "function") {
|
|
13049
13158
|
return this.args.filter(item, input);
|
|
13050
13159
|
} else {
|
|
@@ -13092,5 +13201,5 @@ export {
|
|
|
13092
13201
|
BaseModelService
|
|
13093
13202
|
};
|
|
13094
13203
|
|
|
13095
|
-
//# debugId=
|
|
13204
|
+
//# debugId=9D73859281C0828564756E2164756E21
|
|
13096
13205
|
//# sourceMappingURL=index.js.map
|