@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
|
@@ -630,4 +630,311 @@ describe('ModelService', () => {
|
|
|
630
630
|
expect(results).toEqual(inputs)
|
|
631
631
|
})
|
|
632
632
|
})
|
|
633
|
+
|
|
634
|
+
describe('Trash Functionality', () => {
|
|
635
|
+
const beforeEmptyTrashSpy = mock((event) => {})
|
|
636
|
+
const afterEmptyTrashSpy = mock((event) => {})
|
|
637
|
+
const beforePermanentlyDeleteFromTrashSpy = mock((event) => {})
|
|
638
|
+
const afterPermanentlyDeleteFromTrashSpy = mock((event) => {})
|
|
639
|
+
const beforePermanentlyDeleteSpy = mock((event) => {})
|
|
640
|
+
const afterPermanentlyDeleteSpy = mock((event) => {})
|
|
641
|
+
|
|
642
|
+
beforeEach(() => {
|
|
643
|
+
emitter.on('books::book.beforeEmptyTrash', beforeEmptyTrashSpy)
|
|
644
|
+
emitter.on('books::book.afterEmptyTrash', afterEmptyTrashSpy)
|
|
645
|
+
emitter.on('books::book.beforePermanentlyDeleteFromTrash', beforePermanentlyDeleteFromTrashSpy)
|
|
646
|
+
emitter.on('books::book.afterPermanentlyDeleteFromTrash', afterPermanentlyDeleteFromTrashSpy)
|
|
647
|
+
emitter.on('books::book.beforePermanentlyDelete', beforePermanentlyDeleteSpy)
|
|
648
|
+
emitter.on('books::book.afterPermanentlyDelete', afterPermanentlyDeleteSpy)
|
|
649
|
+
|
|
650
|
+
beforeEmptyTrashSpy.mockClear()
|
|
651
|
+
afterEmptyTrashSpy.mockClear()
|
|
652
|
+
beforePermanentlyDeleteFromTrashSpy.mockClear()
|
|
653
|
+
afterPermanentlyDeleteFromTrashSpy.mockClear()
|
|
654
|
+
beforePermanentlyDeleteSpy.mockClear()
|
|
655
|
+
afterPermanentlyDeleteSpy.mockClear()
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
describe('emptyTrash', () => {
|
|
659
|
+
it('should permanently delete all items from trash', async () => {
|
|
660
|
+
// Create and remove multiple items
|
|
661
|
+
const book1 = await repository.create({
|
|
662
|
+
title: 'Book 1',
|
|
663
|
+
author: 'Author 1',
|
|
664
|
+
publishedDate: new Date(),
|
|
665
|
+
})
|
|
666
|
+
const book2 = await repository.create({
|
|
667
|
+
title: 'Book 2',
|
|
668
|
+
author: 'Author 2',
|
|
669
|
+
publishedDate: new Date(),
|
|
670
|
+
})
|
|
671
|
+
const book3 = await repository.create({
|
|
672
|
+
title: 'Book 3',
|
|
673
|
+
author: 'Author 3',
|
|
674
|
+
publishedDate: new Date(),
|
|
675
|
+
})
|
|
676
|
+
|
|
677
|
+
await repository.remove({ id: book1.id })
|
|
678
|
+
await repository.remove({ id: book2.id })
|
|
679
|
+
await repository.remove({ id: book3.id })
|
|
680
|
+
|
|
681
|
+
// Empty trash
|
|
682
|
+
const count = await service.emptyTrash()
|
|
683
|
+
|
|
684
|
+
expect(count).toBe(3)
|
|
685
|
+
|
|
686
|
+
// Verify items are no longer in trash
|
|
687
|
+
const inTrash1 = await repository.load({ id: book1.id }, { removedOnly: true })
|
|
688
|
+
const inTrash2 = await repository.load({ id: book2.id }, { removedOnly: true })
|
|
689
|
+
const inTrash3 = await repository.load({ id: book3.id }, { removedOnly: true })
|
|
690
|
+
|
|
691
|
+
expect(inTrash1).toBeNull()
|
|
692
|
+
expect(inTrash2).toBeNull()
|
|
693
|
+
expect(inTrash3).toBeNull()
|
|
694
|
+
})
|
|
695
|
+
|
|
696
|
+
it('should permanently delete filtered items from trash', async () => {
|
|
697
|
+
const repositoryWithFilter = new MockMemoryRepository({
|
|
698
|
+
schema: mockSchema,
|
|
699
|
+
filter: (data, filters) => {
|
|
700
|
+
if (filters.text) {
|
|
701
|
+
return data.title.toLowerCase().includes(filters.text.toLowerCase())
|
|
702
|
+
}
|
|
703
|
+
return true
|
|
704
|
+
},
|
|
705
|
+
})
|
|
706
|
+
|
|
707
|
+
const serviceWithFilter = new ModelService({
|
|
708
|
+
repository: repositoryWithFilter,
|
|
709
|
+
emitter,
|
|
710
|
+
schema: mockSchema,
|
|
711
|
+
namespace,
|
|
712
|
+
})
|
|
713
|
+
|
|
714
|
+
const book1 = await repositoryWithFilter.create({
|
|
715
|
+
title: 'Test Book 1',
|
|
716
|
+
author: 'Author 1',
|
|
717
|
+
publishedDate: new Date(),
|
|
718
|
+
})
|
|
719
|
+
const book2 = await repositoryWithFilter.create({
|
|
720
|
+
title: 'Test Book 2',
|
|
721
|
+
author: 'Author 2',
|
|
722
|
+
publishedDate: new Date(),
|
|
723
|
+
})
|
|
724
|
+
const book3 = await repositoryWithFilter.create({
|
|
725
|
+
title: 'Other Book',
|
|
726
|
+
author: 'Author 3',
|
|
727
|
+
publishedDate: new Date(),
|
|
728
|
+
})
|
|
729
|
+
|
|
730
|
+
await repositoryWithFilter.remove({ id: book1.id })
|
|
731
|
+
await repositoryWithFilter.remove({ id: book2.id })
|
|
732
|
+
await repositoryWithFilter.remove({ id: book3.id })
|
|
733
|
+
|
|
734
|
+
// Empty trash with filter
|
|
735
|
+
const count = await serviceWithFilter.emptyTrash({ text: 'Test' })
|
|
736
|
+
|
|
737
|
+
expect(count).toBe(2)
|
|
738
|
+
|
|
739
|
+
// Verify only filtered items were deleted
|
|
740
|
+
const inTrash1 = await repositoryWithFilter.load({ id: book1.id }, { removedOnly: true })
|
|
741
|
+
const inTrash2 = await repositoryWithFilter.load({ id: book2.id }, { removedOnly: true })
|
|
742
|
+
const inTrash3 = await repositoryWithFilter.load({ id: book3.id }, { removedOnly: true })
|
|
743
|
+
|
|
744
|
+
expect(inTrash1).toBeNull()
|
|
745
|
+
expect(inTrash2).toBeNull()
|
|
746
|
+
expect(inTrash3).not.toBeNull()
|
|
747
|
+
expect(inTrash3?.title).toBe('Other Book')
|
|
748
|
+
})
|
|
749
|
+
|
|
750
|
+
it('should return 0 when trash is empty', async () => {
|
|
751
|
+
const count = await service.emptyTrash()
|
|
752
|
+
expect(count).toBe(0)
|
|
753
|
+
})
|
|
754
|
+
|
|
755
|
+
it('should trigger before and after events for emptyTrash', async () => {
|
|
756
|
+
const book = await repository.create({
|
|
757
|
+
title: 'Book to Remove',
|
|
758
|
+
author: 'Author',
|
|
759
|
+
publishedDate: new Date(),
|
|
760
|
+
})
|
|
761
|
+
await repository.remove({ id: book.id })
|
|
762
|
+
|
|
763
|
+
await service.emptyTrash()
|
|
764
|
+
|
|
765
|
+
expect(beforeEmptyTrashSpy).toHaveBeenCalledTimes(1)
|
|
766
|
+
expect(beforeEmptyTrashSpy).toHaveBeenCalledWith(
|
|
767
|
+
expect.objectContaining({ type: 'books::book.beforeEmptyTrash' }),
|
|
768
|
+
)
|
|
769
|
+
expect(afterEmptyTrashSpy).toHaveBeenCalledTimes(1)
|
|
770
|
+
expect(afterEmptyTrashSpy).toHaveBeenCalledWith(
|
|
771
|
+
expect.objectContaining({ type: 'books::book.afterEmptyTrash' }),
|
|
772
|
+
)
|
|
773
|
+
})
|
|
774
|
+
|
|
775
|
+
it('should not affect non-removed items', async () => {
|
|
776
|
+
await repository.create({ title: 'Active Book 1', author: 'Author 1', publishedDate: new Date() })
|
|
777
|
+
await repository.create({ title: 'Active Book 2', author: 'Author 2', publishedDate: new Date() })
|
|
778
|
+
|
|
779
|
+
const book3 = await repository.create({
|
|
780
|
+
title: 'Book to Remove',
|
|
781
|
+
author: 'Author 3',
|
|
782
|
+
publishedDate: new Date(),
|
|
783
|
+
})
|
|
784
|
+
await repository.remove({ id: book3.id })
|
|
785
|
+
|
|
786
|
+
// Empty trash
|
|
787
|
+
await service.emptyTrash()
|
|
788
|
+
|
|
789
|
+
// Verify active items are still there
|
|
790
|
+
const results = await repository.search({})
|
|
791
|
+
expect(results.results).toHaveLength(2)
|
|
792
|
+
})
|
|
793
|
+
})
|
|
794
|
+
|
|
795
|
+
describe('permanentlyDeleteFromTrash', () => {
|
|
796
|
+
it('should permanently delete a removed item from trash', async () => {
|
|
797
|
+
const book = await repository.create({
|
|
798
|
+
title: 'Book to Delete',
|
|
799
|
+
author: 'Author',
|
|
800
|
+
publishedDate: new Date(),
|
|
801
|
+
})
|
|
802
|
+
|
|
803
|
+
// Remove the book
|
|
804
|
+
await repository.remove({ id: book.id })
|
|
805
|
+
|
|
806
|
+
// Verify it's in trash
|
|
807
|
+
const inTrash = await repository.load({ id: book.id }, { removedOnly: true })
|
|
808
|
+
expect(inTrash).not.toBeNull()
|
|
809
|
+
|
|
810
|
+
// Permanently delete from trash
|
|
811
|
+
const deleted = await service.permanentlyDeleteFromTrash({ id: book.id })
|
|
812
|
+
|
|
813
|
+
expect(deleted.id).toBe(book.id)
|
|
814
|
+
expect(deleted.title).toBe('Book to Delete')
|
|
815
|
+
|
|
816
|
+
// Verify it's no longer in trash
|
|
817
|
+
const afterDelete = await repository.load({ id: book.id }, { removedOnly: true })
|
|
818
|
+
expect(afterDelete).toBeNull()
|
|
819
|
+
|
|
820
|
+
// Verify it's not in main data either
|
|
821
|
+
const inMain = await repository.load({ id: book.id })
|
|
822
|
+
expect(inMain).toBeNull()
|
|
823
|
+
})
|
|
824
|
+
|
|
825
|
+
it('should throw error when trying to delete non-existent item from trash', async () => {
|
|
826
|
+
await expect(service.permanentlyDeleteFromTrash({ id: 999 })).rejects.toThrow()
|
|
827
|
+
})
|
|
828
|
+
|
|
829
|
+
it('should throw error when trying to delete active item from trash', async () => {
|
|
830
|
+
const book = await repository.create({
|
|
831
|
+
title: 'Active Book',
|
|
832
|
+
author: 'Author',
|
|
833
|
+
publishedDate: new Date(),
|
|
834
|
+
})
|
|
835
|
+
|
|
836
|
+
// Should fail because item is not in trash
|
|
837
|
+
await expect(service.permanentlyDeleteFromTrash({ id: book.id })).rejects.toThrow()
|
|
838
|
+
})
|
|
839
|
+
|
|
840
|
+
it('should trigger before and after events for permanentlyDeleteFromTrash', async () => {
|
|
841
|
+
const book = await repository.create({
|
|
842
|
+
title: 'Book to Delete',
|
|
843
|
+
author: 'Author',
|
|
844
|
+
publishedDate: new Date(),
|
|
845
|
+
})
|
|
846
|
+
await repository.remove({ id: book.id })
|
|
847
|
+
|
|
848
|
+
await service.permanentlyDeleteFromTrash({ id: book.id })
|
|
849
|
+
|
|
850
|
+
expect(beforePermanentlyDeleteFromTrashSpy).toHaveBeenCalledTimes(1)
|
|
851
|
+
expect(beforePermanentlyDeleteFromTrashSpy).toHaveBeenCalledWith(
|
|
852
|
+
expect.objectContaining({ type: 'books::book.beforePermanentlyDeleteFromTrash' }),
|
|
853
|
+
)
|
|
854
|
+
expect(afterPermanentlyDeleteFromTrashSpy).toHaveBeenCalledTimes(1)
|
|
855
|
+
expect(afterPermanentlyDeleteFromTrashSpy).toHaveBeenCalledWith(
|
|
856
|
+
expect.objectContaining({ type: 'books::book.afterPermanentlyDeleteFromTrash' }),
|
|
857
|
+
)
|
|
858
|
+
})
|
|
859
|
+
})
|
|
860
|
+
|
|
861
|
+
describe('permanentlyDelete', () => {
|
|
862
|
+
it('should permanently delete a removed item', async () => {
|
|
863
|
+
const book = await repository.create({
|
|
864
|
+
title: 'Book to Delete',
|
|
865
|
+
author: 'Author',
|
|
866
|
+
publishedDate: new Date(),
|
|
867
|
+
})
|
|
868
|
+
|
|
869
|
+
// Remove the book first
|
|
870
|
+
await repository.remove({ id: book.id })
|
|
871
|
+
|
|
872
|
+
// Verify it's in trash
|
|
873
|
+
const inTrash = await repository.load({ id: book.id }, { removedOnly: true })
|
|
874
|
+
expect(inTrash).not.toBeNull()
|
|
875
|
+
|
|
876
|
+
// Permanently delete
|
|
877
|
+
const deleted = await service.permanentlyDelete({ id: book.id })
|
|
878
|
+
|
|
879
|
+
expect(deleted.id).toBe(book.id)
|
|
880
|
+
expect(deleted.title).toBe('Book to Delete')
|
|
881
|
+
|
|
882
|
+
// Verify it's no longer anywhere
|
|
883
|
+
const afterDelete = await repository.load({ id: book.id }, { removedOnly: true })
|
|
884
|
+
expect(afterDelete).toBeNull()
|
|
885
|
+
|
|
886
|
+
const inMain = await repository.load({ id: book.id })
|
|
887
|
+
expect(inMain).toBeNull()
|
|
888
|
+
})
|
|
889
|
+
|
|
890
|
+
it('should permanently delete an active item', async () => {
|
|
891
|
+
const book = await repository.create({
|
|
892
|
+
title: 'Active Book to Delete',
|
|
893
|
+
author: 'Author',
|
|
894
|
+
publishedDate: new Date(),
|
|
895
|
+
})
|
|
896
|
+
|
|
897
|
+
// Verify it exists
|
|
898
|
+
const exists = await repository.load({ id: book.id })
|
|
899
|
+
expect(exists).not.toBeNull()
|
|
900
|
+
|
|
901
|
+
// Permanently delete without removing first
|
|
902
|
+
const deleted = await service.permanentlyDelete({ id: book.id })
|
|
903
|
+
|
|
904
|
+
expect(deleted.id).toBe(book.id)
|
|
905
|
+
expect(deleted.title).toBe('Active Book to Delete')
|
|
906
|
+
|
|
907
|
+
// Verify it's no longer in main data
|
|
908
|
+
const afterDelete = await repository.load({ id: book.id })
|
|
909
|
+
expect(afterDelete).toBeNull()
|
|
910
|
+
|
|
911
|
+
// Verify it's not in trash either
|
|
912
|
+
const inTrash = await repository.load({ id: book.id }, { removedOnly: true })
|
|
913
|
+
expect(inTrash).toBeNull()
|
|
914
|
+
})
|
|
915
|
+
|
|
916
|
+
it('should throw error when trying to delete non-existent item', async () => {
|
|
917
|
+
await expect(service.permanentlyDelete({ id: 999 })).rejects.toThrow()
|
|
918
|
+
})
|
|
919
|
+
|
|
920
|
+
it('should trigger before and after events for permanentlyDelete', async () => {
|
|
921
|
+
const book = await repository.create({
|
|
922
|
+
title: 'Book to Delete',
|
|
923
|
+
author: 'Author',
|
|
924
|
+
publishedDate: new Date(),
|
|
925
|
+
})
|
|
926
|
+
|
|
927
|
+
await service.permanentlyDelete({ id: book.id })
|
|
928
|
+
|
|
929
|
+
expect(beforePermanentlyDeleteSpy).toHaveBeenCalledTimes(1)
|
|
930
|
+
expect(beforePermanentlyDeleteSpy).toHaveBeenCalledWith(
|
|
931
|
+
expect.objectContaining({ type: 'books::book.beforePermanentlyDelete' }),
|
|
932
|
+
)
|
|
933
|
+
expect(afterPermanentlyDeleteSpy).toHaveBeenCalledTimes(1)
|
|
934
|
+
expect(afterPermanentlyDeleteSpy).toHaveBeenCalledWith(
|
|
935
|
+
expect.objectContaining({ type: 'books::book.afterPermanentlyDelete' }),
|
|
936
|
+
)
|
|
937
|
+
})
|
|
938
|
+
})
|
|
939
|
+
})
|
|
633
940
|
})
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { ActionDescriptor, AnyModelSchema, IActionDescriptor } from '@declaro/core'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
InferDetail,
|
|
4
|
+
InferFilters,
|
|
5
|
+
InferInput,
|
|
6
|
+
InferLookup,
|
|
7
|
+
InferSummary,
|
|
8
|
+
} from '../../shared/utils/schema-inference'
|
|
3
9
|
import { ModelMutationAction, ModelQueryEvent } from '../events/event-types'
|
|
4
10
|
import { MutationEvent } from '../events/mutation-event'
|
|
5
11
|
import type { IModelServiceArgs } from './model-service-args'
|
|
@@ -342,4 +348,85 @@ export class ModelService<TSchema extends AnyModelSchema> extends ReadOnlyModelS
|
|
|
342
348
|
// Return normalized results
|
|
343
349
|
return await Promise.all(results.map((result) => this.normalizeDetail(result)))
|
|
344
350
|
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Permanently deletes all items from trash, optionally filtered by the provided criteria.
|
|
354
|
+
* @param filters Optional filters to apply when selecting items to delete from trash.
|
|
355
|
+
* @returns The count of permanently deleted items.
|
|
356
|
+
*/
|
|
357
|
+
async emptyTrash(filters?: InferFilters<TSchema>): Promise<number> {
|
|
358
|
+
// Emit the before empty trash event
|
|
359
|
+
const beforeEmptyTrashEvent = new MutationEvent<number, InferFilters<TSchema> | undefined>(
|
|
360
|
+
this.getDescriptor(ModelMutationAction.BeforeEmptyTrash),
|
|
361
|
+
filters,
|
|
362
|
+
)
|
|
363
|
+
await this.emitter.emitAsync(beforeEmptyTrashEvent)
|
|
364
|
+
|
|
365
|
+
// Perform the empty trash operation
|
|
366
|
+
const count = await this.repository.emptyTrash(filters)
|
|
367
|
+
|
|
368
|
+
// Emit the after empty trash event
|
|
369
|
+
const afterEmptyTrashEvent = new MutationEvent<number, InferFilters<TSchema> | undefined>(
|
|
370
|
+
this.getDescriptor(ModelMutationAction.AfterEmptyTrash),
|
|
371
|
+
filters,
|
|
372
|
+
).setResult(count)
|
|
373
|
+
await this.emitter.emitAsync(afterEmptyTrashEvent)
|
|
374
|
+
|
|
375
|
+
// Return the count of deleted items
|
|
376
|
+
return count
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Permanently deletes a specific item from trash based on the provided lookup.
|
|
381
|
+
* @param lookup The lookup criteria for the item to permanently delete from trash.
|
|
382
|
+
* @returns The permanently deleted item summary.
|
|
383
|
+
*/
|
|
384
|
+
async permanentlyDeleteFromTrash(lookup: InferLookup<TSchema>): Promise<InferSummary<TSchema>> {
|
|
385
|
+
// Emit the before permanently delete from trash event
|
|
386
|
+
const beforePermanentlyDeleteFromTrashEvent = new MutationEvent<InferSummary<TSchema>, InferLookup<TSchema>>(
|
|
387
|
+
this.getDescriptor(ModelMutationAction.BeforePermanentlyDeleteFromTrash),
|
|
388
|
+
lookup,
|
|
389
|
+
)
|
|
390
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteFromTrashEvent)
|
|
391
|
+
|
|
392
|
+
// Perform the permanent deletion from trash
|
|
393
|
+
const result = await this.repository.permanentlyDeleteFromTrash(lookup)
|
|
394
|
+
|
|
395
|
+
// Emit the after permanently delete from trash event
|
|
396
|
+
const afterPermanentlyDeleteFromTrashEvent = new MutationEvent<InferSummary<TSchema>, InferLookup<TSchema>>(
|
|
397
|
+
this.getDescriptor(ModelMutationAction.AfterPermanentlyDeleteFromTrash),
|
|
398
|
+
lookup,
|
|
399
|
+
).setResult(result)
|
|
400
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteFromTrashEvent)
|
|
401
|
+
|
|
402
|
+
// Return the results of the permanent deletion
|
|
403
|
+
return await this.normalizeSummary(result)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Permanently deletes an item based on the provided lookup, regardless of whether it is active or in trash.
|
|
408
|
+
* @param lookup The lookup criteria for the item to permanently delete.
|
|
409
|
+
* @returns The permanently deleted item summary.
|
|
410
|
+
*/
|
|
411
|
+
async permanentlyDelete(lookup: InferLookup<TSchema>): Promise<InferSummary<TSchema>> {
|
|
412
|
+
// Emit the before permanently delete event
|
|
413
|
+
const beforePermanentlyDeleteEvent = new MutationEvent<InferSummary<TSchema>, InferLookup<TSchema>>(
|
|
414
|
+
this.getDescriptor(ModelMutationAction.BeforePermanentlyDelete),
|
|
415
|
+
lookup,
|
|
416
|
+
)
|
|
417
|
+
await this.emitter.emitAsync(beforePermanentlyDeleteEvent)
|
|
418
|
+
|
|
419
|
+
// Perform the permanent deletion
|
|
420
|
+
const result = await this.repository.permanentlyDelete(lookup)
|
|
421
|
+
|
|
422
|
+
// Emit the after permanently delete event
|
|
423
|
+
const afterPermanentlyDeleteEvent = new MutationEvent<InferSummary<TSchema>, InferLookup<TSchema>>(
|
|
424
|
+
this.getDescriptor(ModelMutationAction.AfterPermanentlyDelete),
|
|
425
|
+
lookup,
|
|
426
|
+
).setResult(result)
|
|
427
|
+
await this.emitter.emitAsync(afterPermanentlyDeleteEvent)
|
|
428
|
+
|
|
429
|
+
// Return the results of the permanent deletion
|
|
430
|
+
return await this.normalizeSummary(result)
|
|
431
|
+
}
|
|
345
432
|
}
|