@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.cjs
CHANGED
|
@@ -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
|
-
|
|
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 (
|
|
12918
|
-
item =
|
|
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 =
|
|
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
|
-
|
|
12983
|
-
|
|
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(
|
|
12997
|
-
this.data.delete(
|
|
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
|
-
|
|
13005
|
-
|
|
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(
|
|
13019
|
-
this.data.set(
|
|
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
|
-
|
|
13086
|
-
|
|
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=
|
|
13234
|
+
//# debugId=E3CA467BBFBED82664756E2164756E21
|
|
13117
13235
|
//# sourceMappingURL=index.cjs.map
|