@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.
- package/dist/browser/index.js +14 -14
- package/dist/browser/index.js.map +11 -11
- package/dist/node/index.cjs +163 -45
- package/dist/node/index.cjs.map +11 -11
- package/dist/node/index.js +163 -45
- package/dist/node/index.js.map +11 -11
- 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/domain-event.d.ts +1 -1
- package/dist/ts/domain/events/domain-event.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/events/mutation-event.d.ts +5 -2
- package/dist/ts/domain/events/mutation-event.d.ts.map +1 -1
- package/dist/ts/domain/events/query-event.d.ts +4 -2
- package/dist/ts/domain/events/query-event.d.ts.map +1 -1
- package/dist/ts/domain/events/request-event.d.ts +17 -2
- package/dist/ts/domain/events/request-event.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/domain-event.ts +1 -1
- package/src/domain/events/event-types.ts +9 -0
- package/src/domain/events/mutation-event.test.ts +369 -17
- package/src/domain/events/mutation-event.ts +10 -2
- package/src/domain/events/query-event.test.ts +218 -18
- package/src/domain/events/query-event.ts +8 -2
- package/src/domain/events/request-event.test.ts +1 -1
- package/src/domain/events/request-event.ts +22 -7
- package/src/domain/interfaces/repository.ts +29 -0
- package/src/domain/services/model-service.normalization.test.ts +6 -6
- package/src/domain/services/model-service.test.ts +311 -7
- 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,17 +235,29 @@ 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 {
|
|
250
|
+
input;
|
|
225
251
|
constructor(descriptor, input, meta = {}) {
|
|
226
252
|
super({
|
|
227
|
-
meta
|
|
228
|
-
...meta,
|
|
229
|
-
input
|
|
230
|
-
},
|
|
253
|
+
meta,
|
|
231
254
|
descriptor
|
|
232
255
|
});
|
|
256
|
+
this.input = input;
|
|
257
|
+
}
|
|
258
|
+
setInput(input) {
|
|
259
|
+
this.input = input;
|
|
260
|
+
return this;
|
|
233
261
|
}
|
|
234
262
|
setMeta(meta) {
|
|
235
263
|
this.meta = { ...this.meta, ...meta };
|
|
@@ -239,6 +267,12 @@ class RequestEvent extends DomainEvent {
|
|
|
239
267
|
this.data = result;
|
|
240
268
|
return this;
|
|
241
269
|
}
|
|
270
|
+
toJSON() {
|
|
271
|
+
return {
|
|
272
|
+
...super.toJSON(),
|
|
273
|
+
input: this.input
|
|
274
|
+
};
|
|
275
|
+
}
|
|
242
276
|
}
|
|
243
277
|
|
|
244
278
|
// src/domain/events/mutation-event.ts
|
|
@@ -12641,7 +12675,7 @@ class ReadOnlyModelService extends BaseModelService {
|
|
|
12641
12675
|
async load(lookup, options) {
|
|
12642
12676
|
const beforeLoadEvent = new QueryEvent(this.getDescriptor("beforeLoad" /* BeforeLoad */, options?.scope), lookup);
|
|
12643
12677
|
await this.emitter.emitAsync(beforeLoadEvent);
|
|
12644
|
-
const details = await this.repository.load(lookup);
|
|
12678
|
+
const details = await this.repository.load(lookup, options);
|
|
12645
12679
|
const afterLoadEvent = new QueryEvent(this.getDescriptor("afterLoad" /* AfterLoad */, options?.scope), lookup).setResult(details);
|
|
12646
12680
|
await this.emitter.emitAsync(afterLoadEvent);
|
|
12647
12681
|
return await this.normalizeDetail(details);
|
|
@@ -12649,7 +12683,7 @@ class ReadOnlyModelService extends BaseModelService {
|
|
|
12649
12683
|
async loadMany(lookups, options) {
|
|
12650
12684
|
const beforeLoadManyEvent = new QueryEvent(this.getDescriptor("beforeLoadMany" /* BeforeLoadMany */, options?.scope), lookups);
|
|
12651
12685
|
await this.emitter.emitAsync(beforeLoadManyEvent);
|
|
12652
|
-
const details = await this.repository.loadMany(lookups);
|
|
12686
|
+
const details = await this.repository.loadMany(lookups, options);
|
|
12653
12687
|
const afterLoadManyEvent = new QueryEvent(this.getDescriptor("afterLoadMany" /* AfterLoadMany */, options?.scope), lookups).setResult(details);
|
|
12654
12688
|
await this.emitter.emitAsync(afterLoadManyEvent);
|
|
12655
12689
|
return await Promise.all(details.map((detail) => this.normalizeDetail(detail)));
|
|
@@ -12821,6 +12855,30 @@ class ModelService extends ReadOnlyModelService {
|
|
|
12821
12855
|
await Promise.all(afterEvents.map((event) => this.emitter.emitAsync(event)));
|
|
12822
12856
|
return await Promise.all(results.map((result) => this.normalizeDetail(result)));
|
|
12823
12857
|
}
|
|
12858
|
+
async emptyTrash(filters) {
|
|
12859
|
+
const beforeEmptyTrashEvent = new MutationEvent(this.getDescriptor("beforeEmptyTrash" /* BeforeEmptyTrash */), filters);
|
|
12860
|
+
await this.emitter.emitAsync(beforeEmptyTrashEvent);
|
|
12861
|
+
const count = await this.repository.emptyTrash(filters);
|
|
12862
|
+
const afterEmptyTrashEvent = new MutationEvent(this.getDescriptor("afterEmptyTrash" /* AfterEmptyTrash */), filters).setResult(count);
|
|
12863
|
+
await this.emitter.emitAsync(afterEmptyTrashEvent);
|
|
12864
|
+
return count;
|
|
12865
|
+
}
|
|
12866
|
+
async permanentlyDeleteFromTrash(lookup) {
|
|
12867
|
+
const beforePermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDeleteFromTrash" /* BeforePermanentlyDeleteFromTrash */), lookup);
|
|
12868
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteFromTrashEvent);
|
|
12869
|
+
const result = await this.repository.permanentlyDeleteFromTrash(lookup);
|
|
12870
|
+
const afterPermanentlyDeleteFromTrashEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDeleteFromTrash" /* AfterPermanentlyDeleteFromTrash */), lookup).setResult(result);
|
|
12871
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteFromTrashEvent);
|
|
12872
|
+
return await this.normalizeSummary(result);
|
|
12873
|
+
}
|
|
12874
|
+
async permanentlyDelete(lookup) {
|
|
12875
|
+
const beforePermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("beforePermanentlyDelete" /* BeforePermanentlyDelete */), lookup);
|
|
12876
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteEvent);
|
|
12877
|
+
const result = await this.repository.permanentlyDelete(lookup);
|
|
12878
|
+
const afterPermanentlyDeleteEvent = new MutationEvent(this.getDescriptor("afterPermanentlyDelete" /* AfterPermanentlyDelete */), lookup).setResult(result);
|
|
12879
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteEvent);
|
|
12880
|
+
return await this.normalizeSummary(result);
|
|
12881
|
+
}
|
|
12824
12882
|
}
|
|
12825
12883
|
// src/test/mock/models/mock-book-models.ts
|
|
12826
12884
|
import { ModelSchema as ModelSchema2 } from "@declaro/core";
|
|
@@ -12870,15 +12928,39 @@ class MockMemoryRepository {
|
|
|
12870
12928
|
throw new Error("Primary key must be specified for MockMemoryRepository");
|
|
12871
12929
|
}
|
|
12872
12930
|
}
|
|
12873
|
-
|
|
12931
|
+
findOne(lookup, map2) {
|
|
12932
|
+
if (typeof this.args.lookup === "function") {
|
|
12933
|
+
return Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
|
|
12934
|
+
} else {
|
|
12935
|
+
return map2.get(lookup[this.entityMetadata.primaryKey]);
|
|
12936
|
+
}
|
|
12937
|
+
}
|
|
12938
|
+
findOneWithKey(lookup, map2) {
|
|
12939
|
+
if (typeof this.args.lookup === "function") {
|
|
12940
|
+
const item = Array.from(map2.values()).find((data) => this.args.lookup(data, lookup));
|
|
12941
|
+
if (item) {
|
|
12942
|
+
return { item, key: item[this.entityMetadata.primaryKey] };
|
|
12943
|
+
}
|
|
12944
|
+
} else {
|
|
12945
|
+
const key = lookup[this.entityMetadata.primaryKey];
|
|
12946
|
+
const item = map2.get(key);
|
|
12947
|
+
if (item) {
|
|
12948
|
+
return { item, key };
|
|
12949
|
+
}
|
|
12950
|
+
}
|
|
12951
|
+
return;
|
|
12952
|
+
}
|
|
12953
|
+
async load(input, options = {}) {
|
|
12874
12954
|
if (!this.entityMetadata?.primaryKey) {
|
|
12875
12955
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12876
12956
|
}
|
|
12877
12957
|
let item;
|
|
12878
|
-
if (
|
|
12879
|
-
item =
|
|
12958
|
+
if (options.removedOnly) {
|
|
12959
|
+
item = this.findOne(input, this.trash);
|
|
12960
|
+
} else if (options.includeRemoved) {
|
|
12961
|
+
item = this.findOne(input, this.data) ?? this.findOne(input, this.trash);
|
|
12880
12962
|
} else {
|
|
12881
|
-
item =
|
|
12963
|
+
item = this.findOne(input, this.data);
|
|
12882
12964
|
}
|
|
12883
12965
|
return item || null;
|
|
12884
12966
|
}
|
|
@@ -12902,7 +12984,7 @@ class MockMemoryRepository {
|
|
|
12902
12984
|
}
|
|
12903
12985
|
async search(input, options) {
|
|
12904
12986
|
const pagination = options?.pagination || { page: 1, pageSize: 25 };
|
|
12905
|
-
let items = this.applyFilters(input);
|
|
12987
|
+
let items = this.applyFilters(input, options);
|
|
12906
12988
|
if (options?.sort && Array.isArray(options.sort)) {
|
|
12907
12989
|
items = items.sort((a, b) => {
|
|
12908
12990
|
for (const sortField of options.sort) {
|
|
@@ -12940,45 +13022,25 @@ class MockMemoryRepository {
|
|
|
12940
13022
|
if (!this.entityMetadata?.primaryKey) {
|
|
12941
13023
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12942
13024
|
}
|
|
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) {
|
|
13025
|
+
const found = this.findOneWithKey(lookup, this.data);
|
|
13026
|
+
if (!found) {
|
|
12955
13027
|
throw new Error("Item not found");
|
|
12956
13028
|
}
|
|
12957
|
-
this.trash.set(
|
|
12958
|
-
this.data.delete(
|
|
12959
|
-
return item;
|
|
13029
|
+
this.trash.set(found.key, found.item);
|
|
13030
|
+
this.data.delete(found.key);
|
|
13031
|
+
return found.item;
|
|
12960
13032
|
}
|
|
12961
13033
|
async restore(lookup) {
|
|
12962
13034
|
if (!this.entityMetadata?.primaryKey) {
|
|
12963
13035
|
throw new Error("Primary key is not defined in the schema metadata");
|
|
12964
13036
|
}
|
|
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) {
|
|
13037
|
+
const found = this.findOneWithKey(lookup, this.trash);
|
|
13038
|
+
if (!found) {
|
|
12977
13039
|
throw new Error("Item not found in trash");
|
|
12978
13040
|
}
|
|
12979
|
-
this.trash.delete(
|
|
12980
|
-
this.data.set(
|
|
12981
|
-
return item;
|
|
13041
|
+
this.trash.delete(found.key);
|
|
13042
|
+
this.data.set(found.key, found.item);
|
|
13043
|
+
return found.item;
|
|
12982
13044
|
}
|
|
12983
13045
|
async create(input) {
|
|
12984
13046
|
if (!this.entityMetadata?.primaryKey) {
|
|
@@ -13024,7 +13086,7 @@ class MockMemoryRepository {
|
|
|
13024
13086
|
return updatedItem;
|
|
13025
13087
|
}
|
|
13026
13088
|
async count(search, options) {
|
|
13027
|
-
const filteredItems = this.applyFilters(search);
|
|
13089
|
+
const filteredItems = this.applyFilters(search, options);
|
|
13028
13090
|
return filteredItems.length;
|
|
13029
13091
|
}
|
|
13030
13092
|
async upsert(input, options) {
|
|
@@ -13043,8 +13105,64 @@ class MockMemoryRepository {
|
|
|
13043
13105
|
async bulkUpsert(inputs, options) {
|
|
13044
13106
|
return await Promise.all(inputs.map((input) => this.upsert(input, options)));
|
|
13045
13107
|
}
|
|
13046
|
-
|
|
13047
|
-
|
|
13108
|
+
async permanentlyDelete(lookup) {
|
|
13109
|
+
if (!this.entityMetadata?.primaryKey) {
|
|
13110
|
+
throw new Error("Primary key is not defined in the schema metadata");
|
|
13111
|
+
}
|
|
13112
|
+
const foundInData = this.findOneWithKey(lookup, this.data);
|
|
13113
|
+
if (foundInData) {
|
|
13114
|
+
this.data.delete(foundInData.key);
|
|
13115
|
+
return foundInData.item;
|
|
13116
|
+
}
|
|
13117
|
+
const foundInTrash = this.findOneWithKey(lookup, this.trash);
|
|
13118
|
+
if (foundInTrash) {
|
|
13119
|
+
this.trash.delete(foundInTrash.key);
|
|
13120
|
+
return foundInTrash.item;
|
|
13121
|
+
}
|
|
13122
|
+
throw new Error("Item not found");
|
|
13123
|
+
}
|
|
13124
|
+
async permanentlyDeleteFromTrash(lookup) {
|
|
13125
|
+
if (!this.entityMetadata?.primaryKey) {
|
|
13126
|
+
throw new Error("Primary key is not defined in the schema metadata");
|
|
13127
|
+
}
|
|
13128
|
+
const found = this.findOneWithKey(lookup, this.trash);
|
|
13129
|
+
if (!found) {
|
|
13130
|
+
throw new Error("Item not found in trash");
|
|
13131
|
+
}
|
|
13132
|
+
this.trash.delete(found.key);
|
|
13133
|
+
return found.item;
|
|
13134
|
+
}
|
|
13135
|
+
async emptyTrash(filters) {
|
|
13136
|
+
if (!filters || Object.keys(filters).length === 0) {
|
|
13137
|
+
const count = this.trash.size;
|
|
13138
|
+
this.trash.clear();
|
|
13139
|
+
return count;
|
|
13140
|
+
}
|
|
13141
|
+
const itemsToDelete = [];
|
|
13142
|
+
for (const [key, item] of this.trash.entries()) {
|
|
13143
|
+
if (typeof this.args.filter === "function") {
|
|
13144
|
+
if (this.args.filter(item, filters)) {
|
|
13145
|
+
itemsToDelete.push(key);
|
|
13146
|
+
}
|
|
13147
|
+
} else {
|
|
13148
|
+
itemsToDelete.push(key);
|
|
13149
|
+
}
|
|
13150
|
+
}
|
|
13151
|
+
for (const key of itemsToDelete) {
|
|
13152
|
+
this.trash.delete(key);
|
|
13153
|
+
}
|
|
13154
|
+
return itemsToDelete.length;
|
|
13155
|
+
}
|
|
13156
|
+
applyFilters(input, options) {
|
|
13157
|
+
let sourceItems;
|
|
13158
|
+
if (options?.removedOnly) {
|
|
13159
|
+
sourceItems = Array.from(this.trash.values());
|
|
13160
|
+
} else if (options?.includeRemoved) {
|
|
13161
|
+
sourceItems = [...Array.from(this.data.values()), ...Array.from(this.trash.values())];
|
|
13162
|
+
} else {
|
|
13163
|
+
sourceItems = Array.from(this.data.values());
|
|
13164
|
+
}
|
|
13165
|
+
return sourceItems.filter((item) => {
|
|
13048
13166
|
if (typeof this.args.filter === "function") {
|
|
13049
13167
|
return this.args.filter(item, input);
|
|
13050
13168
|
} else {
|
|
@@ -13092,5 +13210,5 @@ export {
|
|
|
13092
13210
|
BaseModelService
|
|
13093
13211
|
};
|
|
13094
13212
|
|
|
13095
|
-
//# debugId=
|
|
13213
|
+
//# debugId=4FCC17E6392BEFF464756E2164756E21
|
|
13096
13214
|
//# sourceMappingURL=index.js.map
|