Skip to content

Instantly share code, notes, and snippets.

@rhutchison
Last active March 23, 2023 19:26
Show Gist options
  • Save rhutchison/a530d89c37f1978a48dcee4bf2418cb7 to your computer and use it in GitHub Desktop.
Save rhutchison/a530d89c37f1978a48dcee4bf2418cb7 to your computer and use it in GitHub Desktop.
nestjs: TypeOrm 0.3.0
import { Provider, Type } from '@nestjs/common';
import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
import { DataSource, DataSourceOptions, Repository } from 'typeorm';
export function provideCustomRepository<T>(
entity: Type<T>,
repository: Type<Repository<T>>,
dataSource?: DataSource | DataSourceOptions | string
): Provider {
return {
provide: getRepositoryToken(entity),
inject: [getDataSourceToken(dataSource)],
useFactory(dataSource: DataSource) {
const baseRepository = dataSource.getRepository(entity);
return new repository(
baseRepository.target,
baseRepository.manager,
baseRepository.queryRunner
);
},
};
}
import { FindOneOptions, Raw, Repository } from 'typeorm';
import { User } from '../entities';
// remove @EntityRepository decorator
export class UserRepository extends Repository<User> {
async findByEmail(options: { email: string }) {
const searchCriteria = {
join: { alias: 'user', innerJoin: { emails: 'user.emails' } },
where: {
emails: {
address: Raw((alias) => `LOWER(${alias}) = :email`, {
email: options.email.toLowerCase(),
}),
},
},
};
return await this.findOneOrFail(searchCriteria);
}
}
import { provideCustomRepository } from './custom-repository.util';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Email, User } from './entities';
import { UserRepository } from './repositories';
import { UsersService } from './services';
@Module({
imports: [TypeOrmModule.forFeature([Email, User])],
providers: [provideCustomRepository(User, UserRepository), UsersService],
exports: [UsersService],
})
export class UsersDataModule {}
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities';
import { UserRepository } from './repositories';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
protected readonly repository: UserRepository
) {}
}
@ruscon
Copy link

ruscon commented Sep 24, 2022

@InjectRepository(User)

no need if provide: repository, instead of provide: getRepositoryToken(entity),

import { Provider, Type } from '@nestjs/common';
import { getDataSourceToken } from '@nestjs/typeorm';
import { DataSource, DataSourceOptions, Repository } from 'typeorm';

export function provideCustomRepository<Entity extends Record<string, any>, Repo extends Repository<Entity>>(
    entity: Type<Entity>,
    repository: Type<Repo>,
    dataSource?: DataSource | DataSourceOptions | string
): Provider<Repo> {
    return {
        provide: repository,
        inject: [getDataSourceToken(dataSource)],
        useFactory(dataSource: DataSource) {
            const baseRepository = dataSource.getRepository(entity);
            
            return new repository(
                baseRepository.target,
                baseRepository.manager,
                baseRepository.queryRunner
            );
        },
    };
}

@VladisB
Copy link

VladisB commented Nov 27, 2022

@rhutchison Good job! Have you tried writing tests for this service(with util)? Can you share an example?

@cspark0610
Copy link

great example, could you please provide an example on how to create a dataSource file in typeorm 0.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment