feat: add backend-mock app

This commit is contained in:
vben
2024-06-30 14:09:44 +08:00
parent c58aa26dbf
commit ca1cad0cd3
71 changed files with 3420 additions and 735 deletions

View File

@@ -0,0 +1 @@
export * from './public';

View File

@@ -0,0 +1,4 @@
import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

View File

@@ -0,0 +1,40 @@
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
const logFormat = `Request original url: ${request.originalUrl} Method: ${request.method} IP: ${request.ip} Status code: ${status} Response: ${exception.toString()}`;
Logger.error(logFormat);
const resultMessage = exception.message as any;
const message =
resultMessage || `${status >= 500 ? 'Service Error' : 'Client Error'}`;
const errorResponse = {
code: 1,
error: resultMessage,
message,
status,
url: request.originalUrl,
};
response.status(status);
response.header('Content-Type', 'application/json; charset=utf-8');
response.send(errorResponse);
}
}

View File

@@ -0,0 +1 @@
export * from './http-exception.filter';

View File

@@ -0,0 +1,2 @@
export * from './jwt-auth.guard';
export * from './local-auth.guard';

View File

@@ -0,0 +1,23 @@
import { ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { IS_PUBLIC_KEY } from '../decorator/index';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}
canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
return super.canActivate(context);
}
}

View File

@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

View File

@@ -0,0 +1 @@
export * from './transform.interceptor';

View File

@@ -0,0 +1,37 @@
import {
CallHandler,
ExecutionContext,
Injectable,
Logger,
NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class TransformInterceptor implements NestInterceptor {
public intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<any> {
const req = context.getArgByIndex(1).req;
return next.handle().pipe(
map((data) => {
const logFormat = `
Request original url: ${req.originalUrl}
Method: ${req.method}
IP: ${req.ip}
User: ${JSON.stringify(req.user)}
Response data: ${JSON.stringify(data)}
`;
Logger.debug(logFormat);
return {
code: 0,
data,
error: null,
message: 'ok',
};
}),
);
}
}

View File

@@ -0,0 +1 @@
export * from './params.pipe';

View File

@@ -0,0 +1,27 @@
import {
BadRequestException,
HttpStatus,
ValidationPipe,
type ValidationPipeOptions,
} from '@nestjs/common';
class ParamsValidationPipe extends ValidationPipe {
constructor(options: ValidationPipeOptions = {}) {
super({
errorHttpStatusCode: HttpStatus.BAD_REQUEST,
exceptionFactory: (errors) => {
const message = Object.values(errors[0].constraints)[0];
return new BadRequestException({
message,
status: HttpStatus.BAD_REQUEST,
});
},
forbidNonWhitelisted: true,
transform: true,
whitelist: true,
...options,
});
}
}
export { ParamsValidationPipe };