-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseCrudController.ts
105 lines (82 loc) · 2.43 KB
/
BaseCrudController.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import {
Get,
Post,
Patch,
Delete,
Param,
Body,
NotFoundException,
Query,
} from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { Repository, FindOptionsWhere, DataSource } from 'typeorm';
import { ClassType, CrudMethodName } from './types';
export abstract class BaseCrudController<T extends { id: string }> {
protected repository: Repository<T>;
constructor(
model: any,
dataSource: DataSource,
protected validators: Record<CrudMethodName, ClassType> | {} = {},
) {
this.repository = dataSource.getRepository(model);
}
@Get()
async findAll(
@Query('take') take?: number,
@Query('skip') skip?: number,
): Promise<T[]> {
await this.runValidators('findAll', { take, skip });
return this.repository.find({ take: take || 10, skip: skip || 0 });
}
@Get(':id')
async findById(@Param('id') id: string): Promise<T> {
await this.runValidators('findById', { id });
const entity = await this.repository.findOneBy({
id,
} as FindOptionsWhere<T>);
if (!entity) {
throw new NotFoundException('Entity not found');
}
return entity;
}
@Post()
async create(@Body() data: any): Promise<T> {
await this.runValidators('create', data);
const entity = this.repository.create(data as T);
return this.repository.save(entity);
}
@Patch(':id')
async update(@Param('id') id: string, @Body() data: Partial<T>): Promise<T> {
await this.runValidators('update', data);
const entity = await this.repository.findOneBy({
id,
} as FindOptionsWhere<T>);
if (!entity) {
throw new NotFoundException('Entity not found');
}
Object.assign(entity, data);
return this.repository.save(entity);
}
@Delete(':id')
async delete(@Param('id') id: number): Promise<{ isDeleted: boolean }> {
await this.runValidators('delete', { id });
const result = await this.repository.delete(id);
return {
isDeleted: result.affected > 0,
};
}
private async runValidators(
methodName: CrudMethodName,
data: any,
): Promise<void> {
const ValidatorClass = this.validators[methodName];
if (ValidatorClass) {
const validatorInstance = plainToInstance(ValidatorClass, data);
const validationErrors = await validate(validatorInstance);
if (validationErrors.length > 0) {
throw validationErrors;
}
}
}
}