yegara 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.js +18 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/typeorm/audit.entity.d.ts +5 -0
- package/dist/db/typeorm/audit.entity.js +32 -0
- package/dist/db/typeorm/audit.entity.js.map +1 -0
- package/dist/db/typeorm/index.d.ts +3 -0
- package/dist/db/typeorm/index.js +20 -0
- package/dist/db/typeorm/index.js.map +1 -0
- package/dist/db/typeorm/typeorm.config.d.ts +5 -0
- package/dist/db/typeorm/typeorm.config.js +27 -0
- package/dist/db/typeorm/typeorm.config.js.map +1 -0
- package/dist/db/typeorm/typeorm.service.d.ts +8 -0
- package/dist/db/typeorm/typeorm.service.js +30 -0
- package/dist/db/typeorm/typeorm.service.js.map +1 -0
- package/dist/dtos/index.d.ts +1 -0
- package/dist/dtos/index.js +18 -0
- package/dist/dtos/index.js.map +1 -0
- package/dist/dtos/language.dto.d.ts +4 -0
- package/dist/dtos/language.dto.js +36 -0
- package/dist/dtos/language.dto.js.map +1 -0
- package/dist/generics/controllers/extra-crud.controller.d.ts +28 -0
- package/dist/generics/controllers/extra-crud.controller.js +86 -0
- package/dist/generics/controllers/extra-crud.controller.js.map +1 -0
- package/dist/generics/controllers/index.d.ts +2 -0
- package/dist/generics/controllers/index.js +19 -0
- package/dist/generics/controllers/index.js.map +1 -0
- package/dist/generics/controllers/relation-crud.controller.d.ts +23 -0
- package/dist/generics/controllers/relation-crud.controller.js +69 -0
- package/dist/generics/controllers/relation-crud.controller.js.map +1 -0
- package/dist/generics/controllers/schema-crud.controller.d.ts +28 -0
- package/dist/generics/controllers/schema-crud.controller.js +85 -0
- package/dist/generics/controllers/schema-crud.controller.js.map +1 -0
- package/dist/generics/drizzle/controllers/extra-crud.controller.d.ts +28 -0
- package/dist/generics/drizzle/controllers/extra-crud.controller.js +86 -0
- package/dist/generics/drizzle/controllers/extra-crud.controller.js.map +1 -0
- package/dist/generics/drizzle/controllers/index.d.ts +2 -0
- package/dist/generics/drizzle/controllers/index.js +19 -0
- package/dist/generics/drizzle/controllers/index.js.map +1 -0
- package/dist/generics/drizzle/controllers/relation-crud.controller.d.ts +23 -0
- package/dist/generics/drizzle/controllers/relation-crud.controller.js +69 -0
- package/dist/generics/drizzle/controllers/relation-crud.controller.js.map +1 -0
- package/dist/generics/drizzle/controllers/schema-crud.controller.d.ts +28 -0
- package/dist/generics/drizzle/controllers/schema-crud.controller.js +85 -0
- package/dist/generics/drizzle/controllers/schema-crud.controller.js.map +1 -0
- package/dist/generics/drizzle/index.d.ts +2 -0
- package/dist/generics/drizzle/index.js +19 -0
- package/dist/generics/drizzle/index.js.map +1 -0
- package/dist/generics/drizzle/services/extra-crud.service.d.ts +22 -0
- package/dist/generics/drizzle/services/extra-crud.service.js +51 -0
- package/dist/generics/drizzle/services/extra-crud.service.js.map +1 -0
- package/dist/generics/drizzle/services/index.d.ts +2 -0
- package/dist/generics/drizzle/services/index.js +19 -0
- package/dist/generics/drizzle/services/index.js.map +1 -0
- package/dist/generics/drizzle/services/relation-crud.service.d.ts +28 -0
- package/dist/generics/drizzle/services/relation-crud.service.js +90 -0
- package/dist/generics/drizzle/services/relation-crud.service.js.map +1 -0
- package/dist/generics/drizzle/services/schema-crud.service.d.ts +21 -0
- package/dist/generics/drizzle/services/schema-crud.service.js +48 -0
- package/dist/generics/drizzle/services/schema-crud.service.js.map +1 -0
- package/dist/generics/dtos/index.d.ts +1 -0
- package/dist/generics/dtos/index.js +18 -0
- package/dist/generics/dtos/index.js.map +1 -0
- package/dist/generics/dtos/relation-crud.dto.d.ts +8 -0
- package/dist/generics/dtos/relation-crud.dto.js +43 -0
- package/dist/generics/dtos/relation-crud.dto.js.map +1 -0
- package/dist/generics/exceptions/global-filter-exceptions.d.ts +5 -0
- package/dist/generics/exceptions/global-filter-exceptions.js +44 -0
- package/dist/generics/exceptions/global-filter-exceptions.js.map +1 -0
- package/dist/generics/exceptions/index.d.ts +1 -0
- package/dist/generics/exceptions/index.js +18 -0
- package/dist/generics/exceptions/index.js.map +1 -0
- package/dist/generics/index.d.ts +5 -0
- package/dist/generics/index.js +22 -0
- package/dist/generics/index.js.map +1 -0
- package/dist/generics/schemas/audit.schema.d.ts +5 -0
- package/dist/generics/schemas/audit.schema.js +10 -0
- package/dist/generics/schemas/audit.schema.js.map +1 -0
- package/dist/generics/schemas/index.d.ts +1 -0
- package/dist/generics/schemas/index.js +18 -0
- package/dist/generics/schemas/index.js.map +1 -0
- package/dist/generics/services/extra-crud.service.d.ts +22 -0
- package/dist/generics/services/extra-crud.service.js +51 -0
- package/dist/generics/services/extra-crud.service.js.map +1 -0
- package/dist/generics/services/index.d.ts +2 -0
- package/dist/generics/services/index.js +19 -0
- package/dist/generics/services/index.js.map +1 -0
- package/dist/generics/services/relation-crud.service.d.ts +28 -0
- package/dist/generics/services/relation-crud.service.js +90 -0
- package/dist/generics/services/relation-crud.service.js.map +1 -0
- package/dist/generics/services/schema-crud.service.d.ts +21 -0
- package/dist/generics/services/schema-crud.service.js +48 -0
- package/dist/generics/services/schema-crud.service.js.map +1 -0
- package/dist/generics/typeorm/controllers/entity-crud.controller.d.ts +22 -0
- package/dist/generics/typeorm/controllers/entity-crud.controller.js +85 -0
- package/dist/generics/typeorm/controllers/entity-crud.controller.js.map +1 -0
- package/dist/generics/typeorm/controllers/extra-crud.controller.d.ts +22 -0
- package/dist/generics/typeorm/controllers/extra-crud.controller.js +86 -0
- package/dist/generics/typeorm/controllers/extra-crud.controller.js.map +1 -0
- package/dist/generics/typeorm/controllers/index.d.ts +3 -0
- package/dist/generics/typeorm/controllers/index.js +20 -0
- package/dist/generics/typeorm/controllers/index.js.map +1 -0
- package/dist/generics/typeorm/controllers/relation-crud.controller.d.ts +23 -0
- package/dist/generics/typeorm/controllers/relation-crud.controller.js +74 -0
- package/dist/generics/typeorm/controllers/relation-crud.controller.js.map +1 -0
- package/dist/generics/typeorm/index.d.ts +2 -0
- package/dist/generics/typeorm/index.js +19 -0
- package/dist/generics/typeorm/index.js.map +1 -0
- package/dist/generics/typeorm/services/entity-crud.service.d.ts +13 -0
- package/dist/generics/typeorm/services/entity-crud.service.js +50 -0
- package/dist/generics/typeorm/services/entity-crud.service.js.map +1 -0
- package/dist/generics/typeorm/services/extra-crud.service.d.ts +14 -0
- package/dist/generics/typeorm/services/extra-crud.service.js +55 -0
- package/dist/generics/typeorm/services/extra-crud.service.js.map +1 -0
- package/dist/generics/typeorm/services/index.d.ts +3 -0
- package/dist/generics/typeorm/services/index.js +20 -0
- package/dist/generics/typeorm/services/index.js.map +1 -0
- package/dist/generics/typeorm/services/relation-crud.service.d.ts +26 -0
- package/dist/generics/typeorm/services/relation-crud.service.js +98 -0
- package/dist/generics/typeorm/services/relation-crud.service.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/auth/auth.module.d.ts +2 -0
- package/dist/modules/auth/auth.module.js +48 -0
- package/dist/modules/auth/auth.module.js.map +1 -0
- package/dist/modules/auth/decorators/current-user.decorator.d.ts +1 -0
- package/dist/modules/auth/decorators/current-user.decorator.js +9 -0
- package/dist/modules/auth/decorators/current-user.decorator.js.map +1 -0
- package/dist/modules/auth/decorators/index.d.ts +2 -0
- package/dist/modules/auth/decorators/index.js +19 -0
- package/dist/modules/auth/decorators/index.js.map +1 -0
- package/dist/modules/auth/decorators/public.decorator.d.ts +2 -0
- package/dist/modules/auth/decorators/public.decorator.js +8 -0
- package/dist/modules/auth/decorators/public.decorator.js.map +1 -0
- package/dist/modules/auth/dtos/index.d.ts +0 -0
- package/dist/modules/auth/dtos/index.js +1 -0
- package/dist/modules/auth/dtos/index.js.map +1 -0
- package/dist/modules/auth/guards/index.d.ts +1 -0
- package/dist/modules/auth/guards/index.js +18 -0
- package/dist/modules/auth/guards/index.js.map +1 -0
- package/dist/modules/auth/guards/jwt.guard.d.ts +11 -0
- package/dist/modules/auth/guards/jwt.guard.js +51 -0
- package/dist/modules/auth/guards/jwt.guard.js.map +1 -0
- package/dist/modules/auth/index.d.ts +4 -0
- package/dist/modules/auth/index.js +21 -0
- package/dist/modules/auth/index.js.map +1 -0
- package/dist/modules/auth/services/auth.helper.d.ts +13 -0
- package/dist/modules/auth/services/auth.helper.js +137 -0
- package/dist/modules/auth/services/auth.helper.js.map +1 -0
- package/dist/modules/auth/services/index.d.ts +2 -0
- package/dist/modules/auth/services/index.js +19 -0
- package/dist/modules/auth/services/index.js.map +1 -0
- package/dist/modules/auth/services/jwt-strategy.service.d.ts +7 -0
- package/dist/modules/auth/services/jwt-strategy.service.js +33 -0
- package/dist/modules/auth/services/jwt-strategy.service.js.map +1 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +18 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/yegara.module.d.ts +2 -0
- package/dist/yegara.module.js +24 -0
- package/dist/yegara.module.js.map +1 -0
- package/package.json +59 -0
- package/src/db/index.ts +1 -0
- package/src/db/typeorm/audit.entity.ts +13 -0
- package/src/db/typeorm/index.ts +3 -0
- package/src/db/typeorm/typeorm.config.ts +29 -0
- package/src/db/typeorm/typeorm.service.ts +18 -0
- package/src/dtos/index.ts +1 -0
- package/src/dtos/language.dto.ts +20 -0
- package/src/generics/drizzle/controllers/extra-crud.controller.ts +62 -0
- package/src/generics/drizzle/controllers/index.ts +2 -0
- package/src/generics/drizzle/controllers/relation-crud.controller.ts +39 -0
- package/src/generics/drizzle/controllers/schema-crud.controller.ts +60 -0
- package/src/generics/drizzle/index.ts +2 -0
- package/src/generics/drizzle/services/extra-crud.service.ts +44 -0
- package/src/generics/drizzle/services/index.ts +2 -0
- package/src/generics/drizzle/services/relation-crud.service.ts +97 -0
- package/src/generics/drizzle/services/schema-crud.service.ts +39 -0
- package/src/generics/dtos/index.ts +1 -0
- package/src/generics/dtos/relation-crud.dto.ts +24 -0
- package/src/generics/exceptions/global-filter-exceptions.ts +42 -0
- package/src/generics/exceptions/index.ts +1 -0
- package/src/generics/index.ts +5 -0
- package/src/generics/schemas/audit.schema.ts +7 -0
- package/src/generics/schemas/index.ts +1 -0
- package/src/generics/typeorm/controllers/entity-crud.controller.ts +60 -0
- package/src/generics/typeorm/controllers/extra-crud.controller.ts +62 -0
- package/src/generics/typeorm/controllers/index.ts +3 -0
- package/src/generics/typeorm/controllers/relation-crud.controller.ts +46 -0
- package/src/generics/typeorm/index.ts +2 -0
- package/src/generics/typeorm/services/entity-crud.service.ts +39 -0
- package/src/generics/typeorm/services/extra-crud.service.ts +45 -0
- package/src/generics/typeorm/services/index.ts +3 -0
- package/src/generics/typeorm/services/relation-crud.service.ts +90 -0
- package/src/index.ts +4 -0
- package/src/modules/auth/auth.module.ts +35 -0
- package/src/modules/auth/decorators/current-user.decorator.ts +8 -0
- package/src/modules/auth/decorators/index.ts +2 -0
- package/src/modules/auth/decorators/public.decorator.ts +4 -0
- package/src/modules/auth/dtos/index.ts +0 -0
- package/src/modules/auth/guards/index.ts +1 -0
- package/src/modules/auth/guards/jwt.guard.ts +45 -0
- package/src/modules/auth/index.ts +4 -0
- package/src/modules/auth/services/auth.helper.ts +146 -0
- package/src/modules/auth/services/index.ts +2 -0
- package/src/modules/auth/services/jwt-strategy.service.ts +18 -0
- package/src/modules/index.ts +1 -0
- package/src/yegara.module.ts +11 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Body, Controller, Delete, Get, Param, Post, Put, UseInterceptors } from "@nestjs/common";
|
|
2
|
+
import { TEntityCrudService } from "../services/entity-crud.service";
|
|
3
|
+
import { ApiBearerAuth, ApiBody } from "@nestjs/swagger";
|
|
4
|
+
|
|
5
|
+
export type TEntityCrudOptions = {
|
|
6
|
+
createDto?: { new(): NonNullable<unknown> };
|
|
7
|
+
updateDto?: { new(): NonNullable<unknown> };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export function TEntityCrudController<T>(
|
|
12
|
+
options?: TEntityCrudOptions,
|
|
13
|
+
) {
|
|
14
|
+
@Controller()
|
|
15
|
+
@UseInterceptors(/* your interceptors if any */)
|
|
16
|
+
@ApiBearerAuth()
|
|
17
|
+
class SchemaCrudControllerHost {
|
|
18
|
+
constructor(
|
|
19
|
+
public readonly schemaCrudService: TEntityCrudService<T>,
|
|
20
|
+
) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Get()
|
|
24
|
+
async findAll() {
|
|
25
|
+
return await this.schemaCrudService.findAll()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Get('/:id')
|
|
29
|
+
async findOne(
|
|
30
|
+
@Param('id') id: string
|
|
31
|
+
) {
|
|
32
|
+
return await this.schemaCrudService.findOne(id)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Post()
|
|
36
|
+
@ApiBody({ type: options?.createDto })
|
|
37
|
+
async create(
|
|
38
|
+
@Body() itemData: any
|
|
39
|
+
) {
|
|
40
|
+
return await this.schemaCrudService.create(itemData)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Put('/:id')
|
|
44
|
+
@ApiBody({ type: options?.updateDto })
|
|
45
|
+
async update(
|
|
46
|
+
@Param('id') id: string,
|
|
47
|
+
@Body() itemData: any
|
|
48
|
+
) {
|
|
49
|
+
return await this.schemaCrudService.update(id, itemData)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Delete('/:id')
|
|
53
|
+
async delete(
|
|
54
|
+
@Param('id') id: string
|
|
55
|
+
) {
|
|
56
|
+
return await this.schemaCrudService.delete(id)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return SchemaCrudControllerHost
|
|
60
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Body, Controller, Delete, Get, Param, Post, Put, UseInterceptors } from "@nestjs/common";
|
|
2
|
+
import { ApiBearerAuth, ApiBody } from "@nestjs/swagger";
|
|
3
|
+
import { TExtraCrudService } from "../services/extra-crud.service";
|
|
4
|
+
|
|
5
|
+
export type TExtraCrudOptions = {
|
|
6
|
+
createDto?: { new(): NonNullable<unknown> };
|
|
7
|
+
updateDto?: { new(): NonNullable<unknown> };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export function TExtraCrudController<T>(
|
|
12
|
+
options?: TExtraCrudOptions,
|
|
13
|
+
) {
|
|
14
|
+
@Controller()
|
|
15
|
+
@UseInterceptors(/* your interceptors if any */)
|
|
16
|
+
@ApiBearerAuth()
|
|
17
|
+
class ExtraCrudControllerHost {
|
|
18
|
+
constructor(
|
|
19
|
+
public readonly schemaCrudService: TExtraCrudService<T>,
|
|
20
|
+
) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Get('/list/:parentId')
|
|
24
|
+
async findAll(
|
|
25
|
+
@Param('parentId') parentId: string
|
|
26
|
+
) {
|
|
27
|
+
return await this.schemaCrudService.findAll(parentId)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Get('/:id')
|
|
31
|
+
async findOne(
|
|
32
|
+
@Param('id') id: string
|
|
33
|
+
) {
|
|
34
|
+
return await this.schemaCrudService.findOne(id)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Post()
|
|
38
|
+
@ApiBody({ type: options?.createDto })
|
|
39
|
+
async create(
|
|
40
|
+
@Body() itemData: any
|
|
41
|
+
) {
|
|
42
|
+
return await this.schemaCrudService.create(itemData)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Put('/:id')
|
|
46
|
+
@ApiBody({ type: options?.updateDto })
|
|
47
|
+
async update(
|
|
48
|
+
@Param('id') id: string,
|
|
49
|
+
@Body() itemData: any
|
|
50
|
+
) {
|
|
51
|
+
return await this.schemaCrudService.update(id, itemData)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Delete('/:id')
|
|
55
|
+
async delete(
|
|
56
|
+
@Param('id') id: string
|
|
57
|
+
) {
|
|
58
|
+
return await this.schemaCrudService.delete(id)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return ExtraCrudControllerHost
|
|
62
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Body, Controller, Get, Param, Post, UseInterceptors } from "@nestjs/common";
|
|
2
|
+
import { TRelationCrudService } from "../services/relation-crud.service";
|
|
3
|
+
import { AssignSecondForFirstDTO, AssignFirstForSecondDTO } from "../../dtos/relation-crud.dto";
|
|
4
|
+
import { ApiBearerAuth } from "@nestjs/swagger";
|
|
5
|
+
|
|
6
|
+
export function TRelationCrudController<T, U, V>() {
|
|
7
|
+
@Controller()
|
|
8
|
+
@UseInterceptors(/* your interceptors if any */)
|
|
9
|
+
@ApiBearerAuth()
|
|
10
|
+
class TRelationCrudControllerHost {
|
|
11
|
+
constructor(
|
|
12
|
+
public readonly schemaCrudService: TRelationCrudService<T, U, V>,
|
|
13
|
+
) {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Get('/given-first/:id')
|
|
17
|
+
async givenFirst(
|
|
18
|
+
@Param('id') id: string
|
|
19
|
+
) {
|
|
20
|
+
return await this.schemaCrudService.givenFirst(id)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@Get('/given-second/:id')
|
|
24
|
+
async givenSecond(
|
|
25
|
+
@Param('id') id: string
|
|
26
|
+
) {
|
|
27
|
+
return await this.schemaCrudService.givenSecond(id)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Post('assign-firsts-for-second')
|
|
31
|
+
async assignSecond(
|
|
32
|
+
@Body() itemData: AssignFirstForSecondDTO
|
|
33
|
+
) {
|
|
34
|
+
return await this.schemaCrudService.assignFirstsForSecond(itemData.secondId, itemData.firstIds)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Post('assign-seconds-for-first')
|
|
38
|
+
async assignFirst(
|
|
39
|
+
@Body() itemData: AssignSecondForFirstDTO
|
|
40
|
+
) {
|
|
41
|
+
return await this.schemaCrudService.assignSecondsForFirst(itemData.firstId, itemData.secondIds)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return TRelationCrudControllerHost
|
|
46
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { ObjectLiteral, Repository } from "typeorm";
|
|
3
|
+
|
|
4
|
+
@Injectable()
|
|
5
|
+
export class TEntityCrudService<T extends ObjectLiteral> {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly repository: Repository<T>,
|
|
8
|
+
) { }
|
|
9
|
+
|
|
10
|
+
async findAll() {
|
|
11
|
+
const data = await this.repository.find();
|
|
12
|
+
return {
|
|
13
|
+
count: data.length,
|
|
14
|
+
items: data
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async findOne(id: string) {
|
|
19
|
+
return await this.repository.findOne({
|
|
20
|
+
where: {
|
|
21
|
+
id
|
|
22
|
+
} as any
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async create(itemData: any) {
|
|
27
|
+
const items = this.repository.create(itemData);
|
|
28
|
+
await this.repository.insert(items);
|
|
29
|
+
return items;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async update(id: string, itemData: any) {
|
|
33
|
+
return await this.repository.update(id, itemData);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async delete(id: string) {
|
|
37
|
+
return await this.repository.delete(id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { ObjectLiteral, Repository } from "typeorm";
|
|
3
|
+
|
|
4
|
+
@Injectable()
|
|
5
|
+
export class TExtraCrudService<T extends ObjectLiteral> {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly repository: Repository<T>,
|
|
8
|
+
private readonly parentFieldName: string
|
|
9
|
+
) {
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async findAll(parentId: string) {
|
|
13
|
+
const data = await this.repository.find({
|
|
14
|
+
where: {
|
|
15
|
+
[this.parentFieldName]: parentId
|
|
16
|
+
} as any
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
count: data.length,
|
|
20
|
+
items: data
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async findOne(id: string) {
|
|
25
|
+
return await this.repository.findOne({
|
|
26
|
+
where: {
|
|
27
|
+
id
|
|
28
|
+
} as any
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async create(itemData: any) {
|
|
33
|
+
const items = this.repository.create(itemData);
|
|
34
|
+
await this.repository.insert(items);
|
|
35
|
+
return items;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async update(id: string, itemData: any) {
|
|
39
|
+
return await this.repository.update(id, itemData);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async delete(id: string) {
|
|
43
|
+
return await this.repository.delete(id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { eq, getTableColumns } from "drizzle-orm";
|
|
3
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
4
|
+
import { PgTableWithColumns } from "drizzle-orm/pg-core";
|
|
5
|
+
import { ObjectLiteral, Repository } from "typeorm";
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class TRelationCrudService<T extends ObjectLiteral, U extends ObjectLiteral, V extends ObjectLiteral> {
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly repository: Repository<T>,
|
|
11
|
+
private readonly firstRepository: Repository<U>,
|
|
12
|
+
private readonly secondRepository: Repository<V>,
|
|
13
|
+
private readonly repositoryName: string,
|
|
14
|
+
private readonly firstFieldName: string,
|
|
15
|
+
private readonly secondFieldName: string
|
|
16
|
+
) {
|
|
17
|
+
}
|
|
18
|
+
async givenFirst(firstId: string) {
|
|
19
|
+
try {
|
|
20
|
+
const result = await this.secondRepository.find({
|
|
21
|
+
where: {
|
|
22
|
+
[this.repositoryName]: {
|
|
23
|
+
[this.firstFieldName]: firstId
|
|
24
|
+
}
|
|
25
|
+
} as any
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
count: result.length,
|
|
30
|
+
items: result
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Error in givenFirst:', error);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async givenSecond(secondId: string) {
|
|
39
|
+
try {
|
|
40
|
+
|
|
41
|
+
const result = await this.firstRepository.find({
|
|
42
|
+
where: {
|
|
43
|
+
[this.repositoryName]: {
|
|
44
|
+
[this.secondFieldName]: secondId
|
|
45
|
+
}
|
|
46
|
+
} as any
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
count: result.length,
|
|
51
|
+
items: result
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Error in givenSecond:', error);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async assignFirstsForSecond(secondId: string, firstIds: string[]) {
|
|
60
|
+
try {
|
|
61
|
+
const itemData = this.repository.create(firstIds.map((firstId) => ({ [this.firstFieldName]: firstId, [this.secondFieldName]: secondId })) as any);
|
|
62
|
+
await this.repository.insert(itemData);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
count: itemData.length,
|
|
66
|
+
items: itemData
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('Error in assignSecond:', error);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async assignSecondsForFirst(firstId: string, secondsIds: string[]) {
|
|
75
|
+
try {
|
|
76
|
+
const itemData = this.repository.create(secondsIds.map((secondId) => ({ [this.firstFieldName]: firstId, [this.secondFieldName]: secondId })) as any);
|
|
77
|
+
await this.repository.insert(itemData);
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
count: itemData.length,
|
|
82
|
+
items: itemData
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('Error in assignFirst:', error);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Module } from "@nestjs/common";
|
|
2
|
+
import { JwtModule, JwtService } from "@nestjs/jwt";
|
|
3
|
+
import { APP_GUARD, Reflector } from "@nestjs/core";
|
|
4
|
+
import { JwtGuard } from "./guards";
|
|
5
|
+
import { JwtStrategy } from "./services/jwt-strategy.service";
|
|
6
|
+
import { AuthHelper } from "./services/auth.helper";
|
|
7
|
+
import { PassportModule } from "@nestjs/passport";
|
|
8
|
+
|
|
9
|
+
@Module({
|
|
10
|
+
imports: [
|
|
11
|
+
JwtModule.registerAsync({
|
|
12
|
+
useFactory: async () => ({
|
|
13
|
+
secret: process.env.JWT_SECRET || "yrtugbv3gu3ou8923rwgqiowjrw980322",
|
|
14
|
+
signOptions: {
|
|
15
|
+
expiresIn: parseInt(process.env.JWT_EXPIRES_IN!) ?? 3600
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
}),
|
|
21
|
+
PassportModule.register({ defaultStrategy: 'jwt', property: 'user' }),
|
|
22
|
+
// JwtModule.register({}),
|
|
23
|
+
],
|
|
24
|
+
providers: [
|
|
25
|
+
JwtStrategy,
|
|
26
|
+
JwtService,
|
|
27
|
+
Reflector,
|
|
28
|
+
AuthHelper,
|
|
29
|
+
{ provide: APP_GUARD, useClass: JwtGuard },
|
|
30
|
+
],
|
|
31
|
+
exports: [
|
|
32
|
+
JwtService, Reflector, AuthHelper
|
|
33
|
+
]
|
|
34
|
+
})
|
|
35
|
+
export class AuthModule { }
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './jwt.guard'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common";
|
|
2
|
+
import { Request } from "express";
|
|
3
|
+
import { Reflector } from '@nestjs/core';
|
|
4
|
+
import { Observable } from "rxjs";
|
|
5
|
+
import { IS_PUBLIC_KEY } from "../decorators/public.decorator";
|
|
6
|
+
import { AuthHelper } from "../services/auth.helper";
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class JwtGuard implements CanActivate {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly authHelper: AuthHelper,
|
|
12
|
+
private reflector: Reflector
|
|
13
|
+
) { }
|
|
14
|
+
|
|
15
|
+
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
|
|
16
|
+
const request = context.switchToHttp().getRequest()
|
|
17
|
+
|
|
18
|
+
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
|
19
|
+
context.getHandler(),
|
|
20
|
+
context.getClass(),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
if (isPublic) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const token = this.extractTokenFromHeader(request);
|
|
28
|
+
|
|
29
|
+
if (!token) {
|
|
30
|
+
throw new UnauthorizedException(
|
|
31
|
+
'JsonWebTokenError',
|
|
32
|
+
'jwt must be provided',
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const payload = this.authHelper.verifyToken(token);
|
|
36
|
+
request.user = payload
|
|
37
|
+
|
|
38
|
+
return true
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private extractTokenFromHeader(request: Request) {
|
|
42
|
+
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
|
43
|
+
return type === 'Bearer' ? token : undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { BadRequestException, Injectable, UnauthorizedException } from "@nestjs/common";
|
|
2
|
+
import * as bcrypt from 'bcrypt';
|
|
3
|
+
import { JwtService } from "@nestjs/jwt";
|
|
4
|
+
import { randomInt } from "crypto";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class AuthHelper {
|
|
9
|
+
constructor(
|
|
10
|
+
private jwtService: JwtService,
|
|
11
|
+
) { }
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
encryptString(password: string): string {
|
|
15
|
+
const salt: string = bcrypt.genSaltSync(12);
|
|
16
|
+
return bcrypt.hashSync(password, salt);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// generateToken(payload: any) {
|
|
20
|
+
// return this.jwtService.sign(payload)
|
|
21
|
+
// }
|
|
22
|
+
public generateToken(payload: any): string {
|
|
23
|
+
return this.jwtService.sign(
|
|
24
|
+
{ ...payload },
|
|
25
|
+
{
|
|
26
|
+
secret: process.env.JWT_ACCESS_TOKEN_SECRET,
|
|
27
|
+
expiresIn: process.env.JWT_ACCESS_TOKEN_EXPIRES,
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
verifyToken(token: string) {
|
|
32
|
+
const decoded = this.jwtService.verify(token, {
|
|
33
|
+
secret: process.env.JWT_ACCESS_TOKEN_SECRET
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
if (!decoded)
|
|
37
|
+
throw new UnauthorizedException("Invalid token")
|
|
38
|
+
|
|
39
|
+
return decoded
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
comparePassword(password: string, hashedPassword: string) {
|
|
44
|
+
const isValid = bcrypt.compareSync(password, hashedPassword)
|
|
45
|
+
|
|
46
|
+
if (!isValid)
|
|
47
|
+
throw new BadRequestException("Invalid username or password")
|
|
48
|
+
}
|
|
49
|
+
public encodePassword(password: string): string {
|
|
50
|
+
const salt: string = bcrypt.genSaltSync(12);
|
|
51
|
+
return bcrypt.hashSync(password, salt);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public generateOtp(): string {
|
|
55
|
+
const randomNumber = randomInt(1000, 9999)
|
|
56
|
+
return randomNumber.toString()
|
|
57
|
+
}
|
|
58
|
+
public compareHashedValue(
|
|
59
|
+
originalValue: string,
|
|
60
|
+
hashedValue: string,
|
|
61
|
+
): boolean {
|
|
62
|
+
return bcrypt.compareSync(originalValue, hashedValue);
|
|
63
|
+
}
|
|
64
|
+
public verifyEmailTemplateForOtp(
|
|
65
|
+
fullName: string,
|
|
66
|
+
username: string,
|
|
67
|
+
otp: string,
|
|
68
|
+
duration: number,
|
|
69
|
+
) {
|
|
70
|
+
return `<!DOCTYPE html>
|
|
71
|
+
<html lang="en">
|
|
72
|
+
<head>
|
|
73
|
+
<meta charset="UTF-8" />
|
|
74
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
75
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
76
|
+
<title>Email Verification</title>
|
|
77
|
+
<link
|
|
78
|
+
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap"
|
|
79
|
+
rel="stylesheet"
|
|
80
|
+
/>
|
|
81
|
+
</head>
|
|
82
|
+
<body style="margin: 0; font-family: 'Poppins', sans-serif; background: #f7f7f7; font-size: 14px;">
|
|
83
|
+
<header>
|
|
84
|
+
<table style="width: 100%; background: #0d7801;">
|
|
85
|
+
<tbody>
|
|
86
|
+
<tr style="height: 60px;">
|
|
87
|
+
<td style="padding: 20px; text-align: left; color: #fff; font-size: 18px;">
|
|
88
|
+
Email Verification
|
|
89
|
+
</td>
|
|
90
|
+
<td style="text-align: right; padding: 20px; color: #fff; font-size: 14px;">
|
|
91
|
+
${new Date().toLocaleDateString()}
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
</tbody>
|
|
95
|
+
</table>
|
|
96
|
+
</header>
|
|
97
|
+
|
|
98
|
+
<main style="padding: 40px 20px;">
|
|
99
|
+
<div style="background: #fff; border-radius: 8px; max-width: 600px; margin: 0 auto; padding: 40px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);">
|
|
100
|
+
<h2 style="font-size: 24px; color: #333; text-align: center;">Hi ${fullName},</h2>
|
|
101
|
+
<p style="font-size: 16px; color: #555; text-align: center; margin-top: 20px;">
|
|
102
|
+
Use the following OTP to complete the verification process for your email address. The OTP is valid for
|
|
103
|
+
<strong>${duration} minutes</strong>. Do not share this code with anyone.
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
<div style="text-align: center; margin-top: 40px;">
|
|
107
|
+
<h3 style="font-size: 20px; color: #333;">Your Username</h3>
|
|
108
|
+
<p style="font-size: 18px; font-weight: 600; color: #0d7801; margin: 10px 0;">${username}</p>
|
|
109
|
+
<h3 style="font-size: 20px; color: #333;">Your OTP</h3>
|
|
110
|
+
<p style="font-size: 36px; font-weight: 600; color: #fff; background-color: #0d7801; padding: 10px 20px; border-radius: 8px; margin: 20px 0;">
|
|
111
|
+
${otp}
|
|
112
|
+
</p>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<p style="text-align: center; color: #888; font-size: 14px; margin-top: 40px;">
|
|
116
|
+
Need help? Contact us at
|
|
117
|
+
<a href="mailto:megp@gmail.com" style="color: #0d7801; text-decoration: none;">megp@gmail.com</a>
|
|
118
|
+
or visit our
|
|
119
|
+
<a href="#" style="color: #0d7801; text-decoration: none;">Help Center</a>
|
|
120
|
+
</p>
|
|
121
|
+
</div>
|
|
122
|
+
</main>
|
|
123
|
+
|
|
124
|
+
<footer style="background: #fff; padding: 20px; text-align: center; font-size: 14px; color: #888;">
|
|
125
|
+
<p style="margin: 0;">© 2022 Company. All rights reserved.</p>
|
|
126
|
+
<div style="margin-top: 10px;">
|
|
127
|
+
<a href="#" style="margin: 0 8px;">
|
|
128
|
+
<img width="24px" alt="Facebook" src="https://archisketch-resources.s3.ap-northeast-2.amazonaws.com/vrstyler/1661502815169_682499/email-template-icon-facebook" />
|
|
129
|
+
</a>
|
|
130
|
+
<a href="#" style="margin: 0 8px;">
|
|
131
|
+
<img width="24px" alt="Instagram" src="https://archisketch-resources.s3.ap-northeast-2.amazonaws.com/vrstyler/1661504218208_684135/email-template-icon-instagram" />
|
|
132
|
+
</a>
|
|
133
|
+
<a href="#" style="margin: 0 8px;">
|
|
134
|
+
<img width="24px" alt="Twitter" src="https://archisketch-resources.s3.ap-northeast-2.amazonaws.com/vrstyler/1661503043040_372004/email-template-icon-twitter" />
|
|
135
|
+
</a>
|
|
136
|
+
<a href="#" style="margin: 0 8px;">
|
|
137
|
+
<img width="24px" alt="Youtube" src="https://archisketch-resources.s3.ap-northeast-2.amazonaws.com/vrstyler/1661503195931_210869/email-template-icon-youtube" />
|
|
138
|
+
</a>
|
|
139
|
+
</div>
|
|
140
|
+
</footer>
|
|
141
|
+
</body>
|
|
142
|
+
</html>
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { PassportStrategy } from '@nestjs/passport';
|
|
3
|
+
import { Strategy, ExtractJwt } from 'passport-jwt';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class JwtStrategy extends PassportStrategy(Strategy) {
|
|
7
|
+
constructor() {
|
|
8
|
+
super({
|
|
9
|
+
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
10
|
+
ignoreExpiration: false,
|
|
11
|
+
secretOrKey: process.env.JWT_SECRET || "yrtugbv3gu3ou8923rwgqiowjrw980322",
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async validate(payload: any) {
|
|
16
|
+
return payload;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './auth'
|