generic factory
This commit is contained in:
parent
d28e029e33
commit
5e1708e505
12 changed files with 118 additions and 16 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
@ -20,6 +20,7 @@
|
|||
"@types/express": "^4.17.17",
|
||||
"@types/node": "^16.18.41",
|
||||
"ts-node": "10.7.0",
|
||||
"ts-transformer-keys": "^0.4.4",
|
||||
"typescript": "^4.5.2"
|
||||
}
|
||||
},
|
||||
|
@ -3039,6 +3040,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/ts-transformer-keys": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-transformer-keys/-/ts-transformer-keys-0.4.4.tgz",
|
||||
"integrity": "sha512-LrqgvaFvar01/5mbunRyeLTSIkqoC2xfcpL/90aDY6vR07DGyH+UaYGdIEsUudnlAw2Sr0pxFgdZvE0QIyI4qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"typescript": ">=2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"@types/express": "^4.17.17",
|
||||
"@types/node": "^16.18.41",
|
||||
"ts-node": "10.7.0",
|
||||
"ts-transformer-keys": "^0.4.4",
|
||||
"typescript": "^4.5.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
import { Request, Response } from "express";
|
||||
import GenericService from "../services/GenericService";
|
||||
import BaseEntity from "../entities/baseEntity";
|
||||
import GenericFactory from "../factories/GenericFactory";
|
||||
import { GenericViewModel } from "../viewmodels/GenericModel";
|
||||
|
||||
export default class GenericController<Service extends GenericService<Repository>, Repository extends BaseEntity> {
|
||||
constructor(protected readonly service: Service) {}
|
||||
export default class GenericController<
|
||||
Service extends GenericService<Repository>,
|
||||
Factory extends GenericFactory<Repository, ViewModel>,
|
||||
Repository extends BaseEntity,
|
||||
ViewModel extends GenericViewModel
|
||||
> {
|
||||
constructor(protected readonly service: Service, protected readonly factory: Factory) {}
|
||||
|
||||
async getAll(req: Request, res: Response): Promise<void> {
|
||||
let data: Array<Repository> = await this.service.getAll();
|
||||
res.json(data);
|
||||
res.json(this.factory.mapArray(data));
|
||||
}
|
||||
|
||||
async getById(req: Request, res: Response): Promise<void> {
|
||||
let id: number = parseInt(req.params.id);
|
||||
let id: string = req.params.id;
|
||||
let data: Repository = await this.service.getById(id);
|
||||
res.json(data);
|
||||
res.json(this.factory.mapSingle(data));
|
||||
}
|
||||
|
||||
async create(req: Request, res: Response): Promise<void> {
|
||||
|
@ -27,7 +34,7 @@ export default class GenericController<Service extends GenericService<Repository
|
|||
}
|
||||
|
||||
async delete(req: Request, res: Response): Promise<void> {
|
||||
let id: number = parseInt(req.params.id);
|
||||
let id: string = req.params.id;
|
||||
await this.service.delete(id);
|
||||
res.sendStatus(204);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,12 @@ import { Request, Response } from "express";
|
|||
import User from "../entities/user";
|
||||
import UserService from "../services/userService";
|
||||
import GenericController from "./GenericController";
|
||||
import { UserViewModel } from "../viewmodels/userModel";
|
||||
import UserFactory from "../factories/userFactory";
|
||||
|
||||
export default class UserController extends GenericController<UserService, User> {
|
||||
export default class UserController extends GenericController<UserService, UserFactory, User, UserViewModel> {
|
||||
constructor() {
|
||||
super(new UserService());
|
||||
super(new UserService(), new UserFactory());
|
||||
}
|
||||
|
||||
// overwrite defined generic controller function
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Entity, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { PrimaryColumn } from "typeorm";
|
||||
|
||||
export default abstract class BaseEntity {
|
||||
@PrimaryGeneratedColumn("increment")
|
||||
id: number;
|
||||
@PrimaryColumn({ generated: "uuid" })
|
||||
id: string;
|
||||
}
|
||||
|
|
25
src/factories/GenericFactory.ts
Normal file
25
src/factories/GenericFactory.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { keys } from "ts-transformer-keys";
|
||||
import BaseEntity from "../entities/baseEntity";
|
||||
import { GenericViewModel } from "../viewmodels/GenericModel";
|
||||
|
||||
export default interface GenericFactory<Repository extends BaseEntity, ViewModel extends GenericViewModel> {
|
||||
mapSingle(row: Repository): ViewModel;
|
||||
mapArray(rows: Repository[]): ViewModel[];
|
||||
}
|
||||
|
||||
// export default class GenericFactory<Repository extends BaseEntity> {
|
||||
// constructor() {}
|
||||
|
||||
// mapSingle<T extends GenericViewModel>(row: Repository): T {
|
||||
// let keysOfT = keys<T>();
|
||||
|
||||
// return keysOfT.reduce((acc, key) => {
|
||||
// acc[key] = (row as any)?.[key];
|
||||
// return acc;
|
||||
// }, {} as T);
|
||||
// }
|
||||
|
||||
// mapArray<T extends GenericViewModel>(rows: Repository[]): T[] {
|
||||
// return rows.map((r) => this.mapSingle<T>(r));
|
||||
// }
|
||||
// }
|
20
src/factories/userFactory.ts
Normal file
20
src/factories/userFactory.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import User from "../entities/user";
|
||||
import { UserViewModel } from "../viewmodels/userModel";
|
||||
import GenericFactory from "./GenericFactory";
|
||||
|
||||
export default class UserFactory implements GenericFactory<User, UserViewModel> {
|
||||
mapSingle(row: User): UserViewModel {
|
||||
return {
|
||||
id: row.id,
|
||||
firstname: row.firstname,
|
||||
};
|
||||
}
|
||||
|
||||
mapArray(rows: User[]): UserViewModel[] {
|
||||
return rows.map((r) => this.mapSingle(r));
|
||||
}
|
||||
|
||||
mapWithX(row: User): Array<{ id: string }> {
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -2,11 +2,15 @@ import express from "express";
|
|||
import GenericController from "../controller/GenericController";
|
||||
import GenericService from "../services/GenericService";
|
||||
import BaseEntity from "../entities/baseEntity";
|
||||
import { GenericViewModel } from "../viewmodels/GenericModel";
|
||||
import GenericFactory from "../factories/GenericFactory";
|
||||
|
||||
export default class GenericRouter<
|
||||
Controller extends GenericController<Service, Repository>,
|
||||
Controller extends GenericController<Service, Factory, Repository, GenericViewModel>,
|
||||
Service extends GenericService<Repository>,
|
||||
Repository extends BaseEntity
|
||||
Factory extends GenericFactory<Repository, ViewModel>,
|
||||
Repository extends BaseEntity,
|
||||
ViewModel extends GenericViewModel
|
||||
> {
|
||||
public router = express.Router({ mergeParams: true });
|
||||
constructor(protected controller: Controller) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import UserController from "../controller/userController";
|
||||
import User from "../entities/user";
|
||||
import UserFactory from "../factories/userFactory";
|
||||
import UserService from "../services/userService";
|
||||
import { UserViewModel } from "../viewmodels/userModel";
|
||||
import GenericRouter from "./GenericRouter";
|
||||
|
||||
export default class UserRouter extends GenericRouter<UserController, UserService, User> {
|
||||
export default class UserRouter extends GenericRouter<UserController, UserService, UserFactory, User, UserViewModel> {
|
||||
constructor() {
|
||||
super(new UserController());
|
||||
// extend generic routes by specific routes
|
||||
|
|
|
@ -10,7 +10,7 @@ export default class GenericService<Repository extends BaseEntity> {
|
|||
return await dataSource.getRepository(this.entity).createQueryBuilder().getMany();
|
||||
}
|
||||
|
||||
async getById(rowId: number): Promise<Repository> {
|
||||
async getById(rowId: string): Promise<Repository> {
|
||||
return await dataSource.getRepository(this.entity).createQueryBuilder().where({ id: rowId }).getOneOrFail();
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ export default class GenericService<Repository extends BaseEntity> {
|
|||
return await dataSource.createQueryBuilder().update(this.entity).set(value).execute();
|
||||
}
|
||||
|
||||
async delete(rowId: number): Promise<DeleteResult> {
|
||||
async delete(rowId: string): Promise<DeleteResult> {
|
||||
return await dataSource.createQueryBuilder().delete().from(this.entity).where({ id: rowId }).execute();
|
||||
}
|
||||
}
|
||||
|
|
13
src/viewmodels/GenericModel.ts
Normal file
13
src/viewmodels/GenericModel.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import BaseEntity from "../entities/baseEntity";
|
||||
|
||||
interface GenericViewModel extends BaseEntity {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface GenericCreateModel {}
|
||||
|
||||
interface GenericUpdateModel extends BaseEntity {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export { GenericViewModel, GenericCreateModel, GenericUpdateModel };
|
17
src/viewmodels/userModel.ts
Normal file
17
src/viewmodels/userModel.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { GenericCreateModel, GenericUpdateModel, GenericViewModel } from "./GenericModel";
|
||||
|
||||
interface UserViewModel extends GenericViewModel {
|
||||
id: string;
|
||||
firstname: string;
|
||||
}
|
||||
|
||||
interface UserCreateModel extends GenericCreateModel {
|
||||
firstname: string;
|
||||
}
|
||||
|
||||
interface UserUpdateModel extends GenericUpdateModel {
|
||||
id: string;
|
||||
firstname: string;
|
||||
}
|
||||
|
||||
export { UserViewModel, UserCreateModel, UserUpdateModel };
|
Loading…
Add table
Reference in a new issue