I am attempting to create a generic service that should take a ‘given’ Entity to perform basic CRUD operations.
Thus far, I have tried:
export type UserEntity<E> = { new (): E } | Function;
class AuthenticationService<E> {
private userEntity: UserEntity<E>;
constructor(userEntity: UserEntity<E>) {
this.userEntity = userEntity;
}
async login(email: string, password: string) {
// const user = await getRepository(this.userEntity).findOneOrFail({ email });
const user = await this.userEntity?.findOneOrFail({ email });
const validPassword = argon2.verify(user?.password, password);
if (!validPassword) {
throw new ErrorHandler(401, ErrorMessage.INVALID_EMAIL_PASSWORD);
}
const accessToken = JWTHelpers.generateToken(user, {
secret: config.ACCESS_TOKEN_SECRET,
expiry: '300s',
});
const refreshToken = JWTHelpers.generateToken(user, {
secret: config.REFRESH_TOKEN_SECRET,
expiry: '1y',
});
user.tokens = user.tokens.concat(refreshToken);
await user.save();
Reflect.deleteProperty(user, 'password');
return { accessToken, refreshToken };
}
This approach doesn’t seem to work and as a result, compiler throws various types of errors – for instance:
-
Property 'findOneOrFail' does not exist on type 'UserEntity<E>'. Property 'findOneOrFail' does not exist on type 'Function'.
Which is thrown from this declaration:
const user: E = await this.userEntity?.findOneOrFail({ email });
-
Property 'password' does not exist on type 'NonNullable<E>'.
–
thrown at:const validPassword = argon2.verify(user?.password, password);
I am very open to suggestions on how to best approach / fix these issues.
Thanks in advance.