import { BaseRepository } from 'typeorm-transactional-cls-hooked' import { EntityDTO, SortEntityDTO, WithoutID } from './types' /** * Abstract class from which all CRUD service classes inherit from * NOTE: No method is marked as @Transactional() because they all changes are atomics * * @template EntityClass The class this service is about * @template EntityRepository The repository associated to the provided entity * @template EntityCreationDTO The creation DTO * @template EntityUpdateDTO The update DTO * @template EntityFilterDTO The filters DTO * @template EntitySortDTO The sort DTO * @template PaginationDTO The pagination DTO */ export abstract class CrudService< Entity extends { id: string }, EntityRepository extends BaseRepository, EntityCreationDTO extends object = WithoutID>, EntityUpdateDTO extends object = Partial>>, EntityFilterDTO extends object = Partial>, EntitySortDTO extends object = SortEntityDTO, PaginationDTO extends { skip: number; take: number } = { skip: number take: number } > { constructor(public readonly repo: EntityRepository) {} /** * Create an entity from its DTO * @param dto The creation DTO * @returns The created entity */ create(dto: EntityCreationDTO): Entity { return this.repo.create(dto) } /** * Update an existing entity * @param id ID of the entity to update * @param dto The update DTO * @returns A promise holding `true` if the entity was updated and `false` if it was not found */ async update(id: string, dto: EntityUpdateDTO): Promise { return (await this.repo.update(id, dto)).generatedMaps.length > 0 } /** * Remove an existing entity * @param id ID of the entity to remove * @returns A promise holding the removed entity or 'undefined' if it was not found */ async removeById(id: string): Promise { const toRemove = await this.repo.findOne(id) return toRemove ? this.repo.remove(toRemove) : undefined } /** * Find a single entity using its identifier * @param id ID of the entity to get * @returns A promise holding the related entity or 'undefined' if it was not found */ findOne(id: Entity['id']): Promise { return this.repo.findOne(id) } /** * Find all entities matching a set of criterias * @param filters Query filters * @param sort Sort order * @param pagination Pagination rules * @returns The list of entities matching the provided set of criterias */ findMany( filters: EntityFilterDTO, sort: EntitySortDTO, pagination: PaginationDTO ): Promise { return this.repo.find({ where: filters, order: sort, skip: pagination.skip, take: pagination.take }) } /** * Save an entity * @param entity The entity to save */ save(entity: Entity): Promise { return this.repo.save(entity as any) } }