Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: Add home number 4 #4

Merged
merged 3 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions 04-request-lifecycle/01-nestjs-components/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { Module } from "@nestjs/common";
import {
MiddlewareConsumer,
Module,
NestModule,
RequestMethod,
} from "@nestjs/common";
import { TasksModule } from "./tasks/tasks.module";
import { LoggingMiddleware } from "./middlewares/logging.middleware";

@Module({
imports: [TasksModule],
})
export class AppModule {}
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggingMiddleware).forRoutes({
path: "ab*cd",
method: RequestMethod.ALL,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

});
}
}
2 changes: 2 additions & 0 deletions 04-request-lifecycle/01-nestjs-components/errors.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[2024-12-31T08:25:54.459Z] 500 - Mock error for testing
[2024-12-31T08:26:13.855Z] 500 - Mock error for testing
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
import { ArgumentsHost, ExceptionFilter } from "@nestjs/common";
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
} from "@nestjs/common";
import * as fs from "fs";

@Catch()
export class HttpErrorFilter implements ExceptionFilter {
catch(exception: any, host: ArgumentsHost) {}
catch(exception: any, host: ArgumentsHost) {
const isHttpException = exception instanceof HttpException;
const status = isHttpException ? exception.getStatus() : 500;
const message = isHttpException
? exception.message
: "Mock error for testing";
const timestamp = new Date().toISOString();
const path = host.switchToHttp().getRequest().path;
const error = null;

const response = host.switchToHttp().getResponse();
response.status(status).json({
statusCode: status,
message,
timestamp,
path,
error,
});

fs.appendFileSync(
"errors.log",
`[${timestamp}] ${status} - ${message}\n`,
);
}
}
21 changes: 18 additions & 3 deletions 04-request-lifecycle/01-nestjs-components/guards/roles.guard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { CanActivate, ExecutionContext } from "@nestjs/common";

import {
CanActivate,
ExecutionContext,
ForbiddenException,
Injectable,
} from "@nestjs/common";
import { Observable } from "rxjs";
@Injectable()
export class RolesGuard implements CanActivate {
canActivate(context: ExecutionContext) {}
canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest();
const role = request.headers["x-role"];

if (role === "admin") {
return true;
} else {
throw new ForbiddenException("Доступ запрещён: требуется роль admin");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { NestInterceptor, ExecutionContext, CallHandler } from "@nestjs/common";
import { Observable, map, tap } from "rxjs";

export class ApiVersionInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const start = Date.now();
let end = 0;
return next.handle().pipe(
tap(() => (end = Date.now() - start)),
map((response) => ({
tasks: response.tasks,
apiVersion: "1.0",
executionTime: end + "ms",
})),
);
}
}
2 changes: 2 additions & 0 deletions 04-request-lifecycle/01-nestjs-components/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { HttpErrorFilter } from "./filters/http-error.filter";

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpErrorFilter());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ import { NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";

export class LoggingMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {}
use(req: Request, res: Response, next: NextFunction) {
console.log( `StringContaining [${req.method}] ${req.path}`);
next();
}
}
14 changes: 12 additions & 2 deletions 04-request-lifecycle/01-nestjs-components/pipes/parse-int.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { PipeTransform } from "@nestjs/common";
import { BadRequestException, HttpStatus, PipeTransform } from "@nestjs/common";

export class ParseIntPipe implements PipeTransform {
transform(value: string): number {}
transform(value: string): number {
const parsedValue = parseInt(value, 10);
if (isNaN(parsedValue)) {
throw new BadRequestException({
statusCode: HttpStatus.BAD_REQUEST,
message: `"${value}" не является числом`,
error: "Bad Request",
});
}
return parsedValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,51 @@ import {
Delete,
Get,
Param,
ParseIntPipe,
Patch,
Post,
UseGuards,
UseInterceptors,
} from "@nestjs/common";
import { TasksService } from "./tasks.service";
import { CreateTaskDto, UpdateTaskDto } from "./task.model";
import { RolesGuard } from "../guards/roles.guard";
import { ApiVersionInterceptor } from "../interceptors/api-version.interceptor";
import { ParseIntPipe } from "../pipes/parse-int.pipe";

@Controller("tasks")
export class TasksController {
constructor(private readonly tasksService: TasksService) {}

@Get()
@UseInterceptors(ApiVersionInterceptor)
getAllTasks() {
return this.tasksService.getAllTasks();
}

@Get(":id")
getTaskById(@Param("id", ParseIntPipe) id: number) {
getTaskById(
@Param("id", new ParseIntPipe())
id: number,
) {
return this.tasksService.getTaskById(id);
}

@Post()
@UseGuards(RolesGuard)
createTask(@Body() task: CreateTaskDto) {
return this.tasksService.createTask(task);
}

@Patch(":id")
updateTask(
@Param("id", ParseIntPipe) id: number,
@Param("id", new ParseIntPipe()) id: number,
@Body() task: UpdateTaskDto,
) {
return this.tasksService.updateTask(id, task);
}

@Delete(":id")
@UseGuards(RolesGuard)
deleteTask(@Param("id", ParseIntPipe) id: number) {
return this.tasksService.deleteTask(id);
}
Expand Down
12 changes: 11 additions & 1 deletion 05-db/01-crud-tasks/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { Module } from "@nestjs/common";
import { TasksModule } from "./tasks/tasks.module";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Task } from "./tasks/entities/task.entity";

@Module({
imports: [TasksModule],
imports: [
TasksModule,
TypeOrmModule.forRoot({
type: "sqlite", // Тип базы данных
database: "db.sqlite", // Файл базы данных
entities: [Task], // Список сущностей
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

как альтернатива можно использова autoLoadEntities

synchronize: true,
}),
],
})
export class AppModule {}
Binary file modified 05-db/01-crud-tasks/db.sqlite
Binary file not shown.
1 change: 0 additions & 1 deletion 05-db/01-crud-tasks/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ValidationPipe } from "@nestjs/common";

async function bootstrap() {
const app = await NestFactory.create(AppModule);
Expand Down
Loading
Loading