From 4c3570a9ce7551b1b18c68783d4e7a2ed73e3e46 Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Fri, 2 Aug 2019 20:17:08 +0700 Subject: [PATCH] Do not extend/modify existing entities Typeorm loads all @Entities and decorator-defined relations into a global variable, and thus makes it impossible to override already defined variables. Will have to think about how to disable this behaviour in case the user of this library does not want to use predefined variables, but for now we will use the predefined defaults. --- .../server/src/application/Application.ts | 30 +++++++++++-------- packages/server/src/application/IServices.ts | 9 ++++++ packages/server/src/application/index.ts | 1 + packages/server/src/entities/UserEmail.ts | 3 -- packages/server/src/index.ts | 1 + packages/server/src/team/TeamService.ts | 24 ++++++++------- packages/server/src/user/UserPermissions.ts | 8 +++-- 7 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 packages/server/src/application/IServices.ts diff --git a/packages/server/src/application/Application.ts b/packages/server/src/application/Application.ts index 98141dc..06fec5a 100644 --- a/packages/server/src/application/Application.ts +++ b/packages/server/src/application/Application.ts @@ -6,13 +6,14 @@ import * as user from '../user' import cookieParser from 'cookie-parser' import express from 'express' import {AsyncRouter, TransactionalRouter} from '../router' +import {DB} from '../database/DB' import {IApplication} from './IApplication' import {IConfig} from './IConfig' import {IDatabase} from '../database/IDatabase' import {ILogger} from '../logger/ILogger' import {IRoutes} from '@rondo/common' +import {IServices} from './IServices' import {ITransactionManager} from '../database/ITransactionManager' -import {DB} from '../database/DB' import {loggerFactory, LoggerFactory} from '../logger/LoggerFactory' import {json} from 'body-parser' @@ -21,10 +22,7 @@ export class Application implements IApplication { readonly transactionManager: ITransactionManager readonly server: express.Application - readonly userService: services.IUserService - readonly teamService: team.ITeamService - readonly userPermissions: user.IUserPermissions - + readonly services: IServices readonly authenticator: middleware.Authenticator readonly loggerFactory: LoggerFactory = loggerFactory @@ -32,16 +30,22 @@ export class Application implements IApplication { constructor(readonly config: IConfig, readonly database: IDatabase) { this.transactionManager = database.transactionManager this.db = new DB(this.transactionManager) - this.userService = new services.UserService(this.db) - this.teamService = new team.TeamService(this.transactionManager) - this.userPermissions = new user.UserPermissions(this.transactionManager) + this.services = this.configureServices() - this.authenticator = new middleware.Authenticator(this.userService) + this.authenticator = new middleware.Authenticator(this.services.userService) this.server = this.createServer() } + protected configureServices(): IServices { + return { + userService: new services.UserService(this.db), + teamService: new team.TeamService(this.db), + userPermissions: new user.UserPermissions(this.db), + } + } + protected getApiLogger(): ILogger { return this.loggerFactory.getLogger('api') } @@ -90,18 +94,18 @@ export class Application implements IApplication { router.use('/app', routes.application) router.use('/api', new routes.LoginRoutes( - this.userService, + this.services.userService, this.authenticator, this.createTransactionalRouter(), ).handle) router.use('/api', new routes.UserRoutes( - this.userService, + this.services.userService, this.createTransactionalRouter(), ).handle) router.use('/api', new team.TeamRoutes( - this.teamService, - this.userPermissions, + this.services.teamService, + this.services.userPermissions, this.createTransactionalRouter(), ).handle) } diff --git a/packages/server/src/application/IServices.ts b/packages/server/src/application/IServices.ts new file mode 100644 index 0000000..8b3fbfa --- /dev/null +++ b/packages/server/src/application/IServices.ts @@ -0,0 +1,9 @@ +import {IUserService} from '../services' +import {ITeamService} from '../team' +import {IUserPermissions} from '../user' + +export interface IServices { + userService: IUserService + teamService: ITeamService + userPermissions: IUserPermissions +} diff --git a/packages/server/src/application/index.ts b/packages/server/src/application/index.ts index 77a8573..611f50d 100644 --- a/packages/server/src/application/index.ts +++ b/packages/server/src/application/index.ts @@ -2,3 +2,4 @@ export * from './Application' export * from './Bootstrap' export * from './IApplication' export * from './IConfig' +export * from './IServices' diff --git a/packages/server/src/entities/UserEmail.ts b/packages/server/src/entities/UserEmail.ts index b38540a..91ea8a0 100644 --- a/packages/server/src/entities/UserEmail.ts +++ b/packages/server/src/entities/UserEmail.ts @@ -4,9 +4,6 @@ import {User} from './User' @Entity() export class UserEmail extends BaseEntity { - @PrimaryGeneratedColumn() - id!: number - @Column({unique: true}) email!: string diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 88d5fe3..05bdf28 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -10,4 +10,5 @@ export * from './routes' export * from './services' export * from './session' export * from './user' +export * from './team' export * from './validator' diff --git a/packages/server/src/team/TeamService.ts b/packages/server/src/team/TeamService.ts index 6f86f01..a8a036b 100644 --- a/packages/server/src/team/TeamService.ts +++ b/packages/server/src/team/TeamService.ts @@ -1,4 +1,4 @@ -import {BaseService} from '../services/BaseService' +import {DB} from '../database/DB' import {ITeamService} from './ITeamService' import {IUserInTeam, trim} from '@rondo/common' import {IUserTeamParams} from './IUserTeamParams' @@ -6,7 +6,9 @@ import {Team} from '../entities/Team' import {UserTeam} from '../entities/UserTeam' import {Validator} from '../validator' -export class TeamService extends BaseService implements ITeamService { +export class TeamService implements ITeamService { + + constructor(protected readonly db: DB) {} // TODO check team limit per user async create({name, userId}: {name: string, userId: number}) { @@ -17,7 +19,7 @@ export class TeamService extends BaseService implements ITeamService { .ensure('userId') .throw() - const team = await this.getRepository(Team).save({ + const team = await this.db.getRepository(Team).save({ name, userId, }) @@ -33,17 +35,17 @@ export class TeamService extends BaseService implements ITeamService { } async remove({id, userId}: {id: number, userId: number}) { - await this.getRepository(UserTeam) + await this.db.getRepository(UserTeam) .delete({teamId: id, userId}) - await this.getRepository(Team) + await this.db.getRepository(Team) .delete(id) return {id} } async update({id, name, userId}: {id: number, name: string, userId: number}) { - await this.getRepository(Team) + await this.db.getRepository(Team) .update({ id, }, { @@ -55,7 +57,7 @@ export class TeamService extends BaseService implements ITeamService { async addUser(params: IUserTeamParams) { const {userId, teamId, roleId} = params - await this.getRepository(UserTeam) + await this.db.getRepository(UserTeam) .save({userId, teamId, roleId}) const userTeam = await this.createFindUserInTeamQuery() @@ -71,7 +73,7 @@ export class TeamService extends BaseService implements ITeamService { async removeUser({teamId, userId, roleId}: IUserTeamParams) { // TODO check if this is the last admin team member - await this.getRepository(UserTeam) + await this.db.getRepository(UserTeam) .delete({userId, teamId, roleId}) } @@ -86,11 +88,11 @@ export class TeamService extends BaseService implements ITeamService { } async findOne(id: number) { - return this.getRepository(Team).findOne(id) + return this.db.getRepository(Team).findOne(id) } async find(userId: number) { - return this.getRepository(Team) + return this.db.getRepository(Team) .createQueryBuilder('team') .select('team') .innerJoin('team.userTeams', 'ut') @@ -99,7 +101,7 @@ export class TeamService extends BaseService implements ITeamService { } protected createFindUserInTeamQuery() { - return this.getRepository(UserTeam) + return this.db.getRepository(UserTeam) .createQueryBuilder('ut') .select('ut') .innerJoinAndSelect('ut.user', 'user') diff --git a/packages/server/src/user/UserPermissions.ts b/packages/server/src/user/UserPermissions.ts index 850b8f7..c4e6e1f 100644 --- a/packages/server/src/user/UserPermissions.ts +++ b/packages/server/src/user/UserPermissions.ts @@ -1,12 +1,14 @@ import createError from 'http-errors' -import {BaseService} from '../services/BaseService' +import {DB} from '../database/DB' import {UserTeam} from '../entities/UserTeam' import {IUserPermissions} from './IUserPermissions' -export class UserPermissions extends BaseService implements IUserPermissions { +export class UserPermissions implements IUserPermissions { + constructor(protected readonly db: DB) {} + async belongsToTeam(params: {userId: number, teamId: number}) { const {userId, teamId} = params - const result = await this.getRepository(UserTeam) + const result = await this.db.getRepository(UserTeam) .findOne({ where: {userId, teamId}, })