I am trying to create a custom repository class that extends Repository.Here is the code
user.service.ts
import { Injectable } from '@nestjs/common';import { InjectRepository } from '@nestjs/typeorm';import { User } from 'src/domain/composite/user/user';import { UserRepository } from 'src/infrastructure/repositories/user/user.repository';import { UserMapper } from 'src/infrastructure/mappers/user/user.mapper';@Injectable()export class UserService { constructor( @InjectRepository(UserRepository) private readonly userRepository: UserRepository, ) {} async findAll(): Promise<User[]> { const users = await this.userRepository.findAll(); return users.map((user) => UserMapper.toDomain(user)); }}
user.repository.ts
import { Injectable } from '@nestjs/common';import { InjectRepository} from "@nestjs/typeorm";import { BaseAbstractRepostitory } from '../common/baseAbstract.repository';import { UserEntity } from 'src/domain/entities/user/user.entity';import { Repository, EntityRepository} from "typeorm";import { BaseInterfaceRepository } from '../common/baseInterface.repository';@Injectable()export class UserRepository extends BaseAbstractRepostitory<UserEntity> implements BaseInterfaceRepository<UserEntity> { constructor(@InjectRepository(UserEntity) userRepository: Repository<UserEntity>) { super(userRepository); } }
base.repository.ts
import { DeepPartial, FindManyOptions, FindOneOptions, FindOperator, Repository, UpdateResult, Equal,} from 'typeorm';import { BaseInterfaceRepository } from './baseInterface.repository';interface HasId { id: string; deleted: boolean;}export abstract class BaseAbstractRepostitory<T extends HasId> implements BaseInterfaceRepository<T>{ private entity: Repository<T>; protected constructor(entity: Repository<T>) { this.entity = entity; } public async findAll( options?: FindManyOptions<T>, deleted: boolean = false, ): Promise<T[]> { if (!options) { options = {}; } // Ensure options.where is defined options.where = options.where || {}; // Update options.where with the 'deleted' flag options.where = { ...(options.where as any), // Cast options.where to 'any' deleted: deleted, }; return this.entity.find(options); }}
domain.module.ts
import { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { UserRepository } from 'src/infrastructure/repositories/user/user.repository';import { UserService } from './service/user/user.service';@Module({ imports: [TypeOrmModule.forFeature([UserRepository])], providers: [UserService], exports: [UserService, TypeOrmModule],})export class DomainModule {}
application.module.ts
import { Module } from '@nestjs/common';import { UserController } from './controller/user/user.controller';import { UserService } from 'src/domain/service/user/user.service';import { DomainModule } from '../domain/domain.module';@Module({ imports: [DomainModule], controllers: [UserController],})export class ApplicationModule {}
This is the folder structure:
so the output of the function when I call the API is:
[Nest] 39455 - 04/02/2024, 2:56:41 PM ERROR [ExceptionsHandler] this.userRepository.findAll is not a function
Also, I followed this guide to create the generic repository
Enhancing Code Reusability with NestJS Abstract Repository Pattern Best Practices and Examples
I read typeorm documentation about custom repositories: https://typeorm.io/custom-repository#how-to-create-custom-repository
StackOverflow:
Github: https://github.com/typeorm/typeorm/issues/2097
Yet nothing is working, is there something wrong with the following code ?