基础
nest --help
# 生成modulenest g mo user
# 生成controllernest g co user
# 生成servicenest g s user
# 生成CRUDnest g res user
# 生成logger中间件nest g mi logger
# 生成user管道nest g pi user
# 创建守卫nest g gu role
# 创建自定义装饰器nest g d userAPI版本控制
Section titled “API版本控制”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { VersioningType } from "@nestjs/common";
async function bootstrap() { const app = await NestFactory.create(AppModule); // 开启版本控制,使用URI方式 app.enableVersioning({ type: VersioningType.URI, }); await app.listen(process.env.PORT ?? 3000);}bootstrap();import { Controller, Get, Post, Body, Patch, Param, Delete, Version,} from "@nestjs/common";import { TService } from "./t.service";import { CreateTDto } from "./dto/create-t.dto";import { UpdateTDto } from "./dto/update-t.dto";
// @Controller('t')@Controller({ path: "t", version: "1", // http://localhost:3000/v1/t})export class TController { constructor(private readonly tService: TService) {}
@Get() // @Version("1") // http://localhost:3000/v1/t findAll() { return this.tService.findAll(); }}import { Controller, Get, Post, Body, Patch, Param, Delete, Version, Request, Query, HttpCode,} from "@nestjs/common";import { TService } from "./t.service";import { CreateTDto } from "./dto/create-t.dto";import { UpdateTDto } from "./dto/update-t.dto";
@Controller("t")export class TController { constructor(private readonly tService: TService) {}
@Post() // create(@Request() req) { // console.log(req.body); // return { // code: 0, // msg: 'success', // data: req.body, // }; // } create(@Body() createTDto: CreateTDto) { console.log(createTDto); return this.tService.create(createTDto); }
@Get() // findAll(@Request() req) { // console.log(req.query); // return this.tService.findAll(); // } @HttpCode(200) findAll(@Query() query) { console.log(query); return this.tService.findAll(); }
@Get(":id") findOne(@Param("id") id: string) { return this.tService.findOne(+id); }}Session
Section titled “Session”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import session from "express-session";import { NestExpressApplication } from "@nestjs/platform-express";
async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.enableCors();
app.use( session({ secret: process.env.SESSION_SECRET || "your-secret-key", rolling: true, resave: false, saveUninitialized: false, cookie: { maxAge: 60 * 60 * 1000, // 1小时 httpOnly: true, }, }), );
await app.listen(process.env.PORT ?? 3000);}bootstrap();import { Controller, Post, Body, Get, Req, Res, Session } from "@nestjs/common";import { AuthService } from "./auth.service";import * as svgCaptcha from "svg-captcha";import { UserLoginDto } from "./dto/user-login.dto";
@Controller("auth")export class AuthController { constructor(private readonly authService: AuthService) {}
@Post("login") login(@Body() userLoginDto: UserLoginDto, @Session() session) { console.log(session.captcha, createAuthDto.code); if ( session.captcha.toLocaleLowerCase() === createAuthDto?.code?.toLocaleLowerCase() ) { return { code: 0, msg: "验证成功", }; } else { return { code: -1, msg: "验证失败", }; } }
@Get("code") getCode(@Req() req, @Res() res, @Session() session) { const captcha = svgCaptcha.create({ size: 4, fontSize: 50, width: 100, height: 34, background: "#cc9966", }); // console.log(captcha);
session.captcha = captcha.text; res.type("image/svg+xml"); res.send(captcha.data); }}<script setup lang="ts">import type { FormInst, FormRules } from "naive-ui";import { useMessage } from "naive-ui";import { ref } from "vue";
interface LoginModel { account: string; password: string; code: string;}
const message = useMessage();const formRef = ref<FormInst | null>(null);const loading = ref(false);
const modelRef = ref<LoginModel>({ account: "", password: "", code: "",});
const rules: FormRules = { account: [ { required: true, message: "请输入账号", trigger: ["blur", "input"], }, ], password: [ { required: true, message: "请输入密码", trigger: ["blur", "input"], }, ],};
async function handleLogin() { if (loading.value) return;
await formRef.value?.validate(async (errors) => { if (errors) { message.error("请填写正确信息"); return; }
try { loading.value = true;
fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(modelRef.value), }) .then((res) => { if (!res.ok) { throw new Error("登录失败"); } return res.json(); }) .then((data) => { if (data.code !== 0) { throw new Error(data.msg); } return data.data; });
message.success("登录成功");
// TODO // router.push('/dashboard') } catch (err) { message.error("登录失败"); } finally { loading.value = false; } });}
function handleKeyDown(e: KeyboardEvent) { if (e.key === "Enter") { handleLogin(); }}
const getCaptchaUrl = ref<string>("/api/auth/code");
const handleCaptchaClick = () => { // getCaptchaUrl.value = `/api/auth/code?${Date.now()}` getCaptchaUrl.value = getCaptchaUrl.value + "?" + Math.random();};</script>
<template> <div class="login-wrapper"> <n-card title="系统登录" class="login-card"> <n-form class="login-form" ref="formRef" :model="modelRef" :rules="rules" :label-width="70" :show-require-mark="false" > <n-form-item path="account" label="账号"> <n-input v-model:value="modelRef.account" type="text" placeholder="请输入账号" @keydown="handleKeyDown" /> </n-form-item> <n-form-item path="password" label="密码"> <n-input v-model:value="modelRef.password" type="password" show-password-on="mousedown" placeholder="请输入密码" @keydown="handleKeyDown" /> </n-form-item> <n-form-item path="code" label="验证码"> <n-input v-model:value="modelRef.code" placeholder="请输入验证码" @keydown="handleKeyDown" /> <img :src="getCaptchaUrl" alt="验证码" @click="handleCaptchaClick" /> </n-form-item> <div class="login-button"> <n-button block type="primary" :loading="loading" @click="handleLogin" > 登录 </n-button> </div> </n-form> </n-card> </div></template>
<style scoped>.login-wrapper { display: flex; align-items: center; justify-content: center;}
.login-card { width: 380px;}
.login-form { text-align: left;}
.login-button { margin-top: 10px;}
:deep(.n-form-item-feedback-wrapper) { text-align: left;}</style>Providers 提供者
Section titled “Providers 提供者”import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";
@Module({ imports: [TModule, AuthModule], controllers: [AppController], providers: [AppService],})export class AppModule {}import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";
@Module({ imports: [TModule, AuthModule], controllers: [AppController], providers: [ { provide: "APP_SERVICE", useClass: AppService, }, ],})export class AppModule {}import { Controller, Get, Inject } from "@nestjs/common";import { AppService } from "./app.service";
@Controller()export class AppController { constructor(@Inject("APP_SERVICE") private readonly appService: AppService) {}}自定义注入值
Section titled “自定义注入值”import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";
@Module({ imports: [TModule, AuthModule], controllers: [AppController], providers: [ { provide: "APP_SERVICE", useClass: AppService, }, { provide: "APP_VALUE", useValue: ["a", "b", "c"], }, ],})export class AppModule {}import { Controller, Get, Inject } from "@nestjs/common";import { AppService } from "./app.service";
@Controller()export class AppController { constructor( @Inject("APP_SERVICE") private readonly appService: AppService, @Inject("APP_VALUE") private readonly appValue: string[], ) {}}import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";
@Module({ imports: [TModule, AuthModule], controllers: [AppController], providers: [ { provide: "APP_SERVICE", useClass: AppService, }, { provide: "APP_VALUE", useValue: ["a", "b", "c"], }, { provide: "APP_FACTORY", useFactory: (appService: AppService) => { return `Factory value: ${appService.getHello()}`; }, inject: ["APP_SERVICE"], }, ],})export class AppModule {}import { Controller, Get, Inject } from "@nestjs/common";import { AppService } from "./app.service";
@Controller()export class AppController { constructor( @Inject("APP_SERVICE") private readonly appService: AppService, @Inject("APP_VALUE") private readonly appValue: string[], @Inject("APP_FACTORY") private readonly appFactory: string, ) {}
@Get() getHello(): string { return this.appService.getHello(); }}Modules 模块
Section titled “Modules 模块”import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";import { UserModule } from "./user/user.module";import { PostModule } from "./post/post.module";
@Module({ imports: [TModule, AuthModule, UserModule, PostModule], controllers: [AppController], providers: [AppService],})export class AppModule {}import { Module } from "@nestjs/common";import { UserService } from "./user.service";import { UserController } from "./user.controller";
@Module({ controllers: [UserController], providers: [UserService], exports: [UserService], // 导出UserService变成共享模块})export class UserModule {}import { Controller, Get, Post, Body, Patch, Param, Delete,} from "@nestjs/common";import { PostService } from "./post.service";import { CreatePostDto } from "./dto/create-post.dto";import { UpdatePostDto } from "./dto/update-post.dto";import { UserService } from "src/user/user.service";
@Controller("post")export class PostController { constructor( private readonly postService: PostService, private readonly userService: UserService, ) {}}import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";import { UserModule } from "./user/user.module";import { PostModule } from "./post/post.module";import { ConfigModule } from "./config/config.module";
@Module({ imports: [TModule, AuthModule, UserModule, PostModule, ConfigModule], controllers: [AppController], providers: [AppService],})export class AppModule {}import { Global, Module } from "@nestjs/common";
@Global()@Module({ providers: [ { provide: "CONFIG", useValue: { baseURL: "/api", }, }, ], exports: ["CONFIG"],})export class ConfigModule {}import { Controller, Get, Post, Body, Patch, Param, Delete, Inject,} from "@nestjs/common";import { UserService } from "./user.service";import { CreateUserDto } from "./dto/create-user.dto";import { UpdateUserDto } from "./dto/update-user.dto";
@Controller("user")export class UserController { constructor( private readonly userService: UserService, @Inject("CONFIG") private config: { baseURL: string }, ) {}}import { Module } from "@nestjs/common";import { AppController } from "./app.controller";import { AppService } from "./app.service";import { TModule } from "./t/t.module";import { AuthModule } from "./auth/auth.module";import { UserModule } from "./user/user.module";import { PostModule } from "./post/post.module";import { ConfigModule } from "./config/config.module";
@Module({ imports: [ TModule, AuthModule, UserModule, PostModule, ConfigModule.forRoot({ path: "/v1" }), ], controllers: [AppController], providers: [AppService],})export class AppModule {}import { DynamicModule, Global, Module } from "@nestjs/common";
interface Options { path: string;}
@Global()@Module({})export class ConfigModule { static forRoot(options: Options): DynamicModule { return { module: ConfigModule, providers: [ { provide: "CONFIG", useValue: { baseURL: "/api" + options.path, }, }, ], exports: ["CONFIG"], }; }}Middleware 中间件
Section titled “Middleware 中间件”依赖注入中间件
Section titled “依赖注入中间件”import { Injectable, NestMiddleware } from "@nestjs/common";import { Request, Response, NextFunction } from "express";
@Injectable()export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log(`${req.method} ${req.originalUrl}`); next(); }}import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";import { UserService } from "./user.service";import { UserController } from "./user.controller";import { LoggerMiddleware } from "src/logger/logger.middleware";
@Module({ controllers: [UserController], providers: [UserService], exports: [UserService],})export class UserModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware).forRoutes("user"); }}import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { Request, Response, NextFunction } from "express";
const whiteList = ["/user"];
function logger(req: Request, res: Response, next: NextFunction) { // console.log(`${req.method} ${req.url}`); // next();
if (whiteList.includes(req.originalUrl)) { next(); } else { res.status(403).json({ msg: "Forbidden" }); }}
async function bootstrap() { const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(process.env.PORT ?? 3000);}bootstrap();使用第三方中间件
Section titled “使用第三方中间件”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";
async function bootstrap() { const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);}bootstrap();Interceptors 拦截器
Section titled “Interceptors 拦截器”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { Response } from "./common/response";
async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule); app.useGlobalInterceptors(new Response()); await app.listen(process.env.PORT ?? 3000);}bootstrap();import { CallHandler, Injectable, NestInterceptor } from "@nestjs/common";import { Observable } from "rxjs";import { map } from "rxjs/operators";
interface Data<T> { data: T;}
@Injectable()export class Response<T> implements NestInterceptor { intercept(context: any, next: CallHandler): Observable<Data<T>> { return next.handle().pipe( map((data) => { return { status: 0, message: "success", success: true, data: data, }; }), ); }}import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { Response } from "./common/response";import { HttpFilter } from "./common/filter";
async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule); app.useGlobalFilters(new HttpFilter()); app.useGlobalInterceptors(new Response()); await app.listen(process.env.PORT ?? 3000);}bootstrap();import { ArgumentsHost, Catch, ExceptionFilter, HttpException,} from "@nestjs/common";import { Request, Response } from "express";
@Catch(HttpException)export class HttpFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const request = ctx.getRequest<Request>(); const response = ctx.getResponse<Response>();
const status = exception.getStatus(); response.status(status).json({ status, success: false, message: exception.message, data: null, time: new Date(), path: request.url, }); }}Pipes 管道
Section titled “Pipes 管道”import { Controller, Get, Param, ParseIntPipe } from "@nestjs/common";import { PService } from "./p.service";
@Controller("p")export class PController { constructor(private readonly pService: PService) {}
@Get(":id") findOne(@Param("id", ParseIntPipe) id: number) { console.log(typeof id); return this.pService.findOne(+id); }}Custom pipes (不推荐)
import { IsNotEmpty, IsString, Length } from "class-validator";
export class UserRegisterDto { @IsNotEmpty() @IsString() @Length(5, 20, { message: "账号长度为5-20个字符", }) account: string;
@IsString() password: string;
@IsString() code: string;}import { PipeTransform, Injectable, ArgumentMetadata, HttpException, HttpStatus,} from "@nestjs/common";import { validate } from "class-validator";import { plainToInstance } from "class-transformer";
@Injectable()export class ValidationPipe implements PipeTransform { async transform(value: any, metadata: ArgumentMetadata) { if (!metadata.metatype || !this.toValidate(metadata.metatype)) { return value; } const object = plainToInstance(metadata.metatype, value); const errors = await validate(object); if (errors.length > 0) { throw new HttpException(errors, HttpStatus.BAD_REQUEST); } return value; }
private toValidate(metatype: Function): boolean { const types: Function[] = [String, Boolean, Number, Array, Object]; return !types.includes(metatype); }}import { Controller, Post, Body, Session } from "@nestjs/common";import { AuthService } from "./auth.service";import { ValidationPipe } from "./validation.pipe";import { UserLoginDto } from "./dto/user-login.dto";
@Controller("auth")export class AuthController { constructor(private readonly authService: AuthService) {}
@Post("login") login(@Body(ValidationPipe) userLoginDto: UserLoginDto, @Session() session) {}}Global scoped pipes (推荐)
async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(process.env.PORT ?? 3000);}bootstrap();Guards 守卫
Section titled “Guards 守卫”守卫在每个中间件之后执行,在每个拦截器或管道之前执行。
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";import { Observable } from "rxjs";import { Reflector } from "@nestjs/core";import type { Request } from "express";
@Injectable()export class AuthGuard implements CanActivate { constructor(private reflector: Reflector) {}
canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { const admin = this.reflector.get<string[]>("role", context.getHandler()); const request = context.switchToHttp().getRequest<Request>(); if (admin.includes(request.query.role as string)) { return true; }
return false; }}import { Controller, Get, Post, Body, Patch, Param, Delete, Inject, UseGuards, SetMetadata,} from "@nestjs/common";import { UserService } from "./user.service";import { CreateUserDto } from "./dto/create-user.dto";import { UpdateUserDto } from "./dto/update-user.dto";import { AuthGuard } from "src/auth.guard";
@Controller("user")@UseGuards(AuthGuard)export class UserController { constructor( private readonly userService: UserService, @Inject("CONFIG") private config: { baseURL: string }, ) {}
@Get() @SetMetadata("role", ["admin"]) findAll() { return this.userService.findAll(); }}Custom decorators 自定义装饰器
Section titled “Custom decorators 自定义装饰器”import { SetMetadata, createParamDecorator, ExecutionContext,} from "@nestjs/common";import type { Request } from "express";
export const Role = (...args: string[]) => SetMetadata("role", args);
// 自定义参数装饰器export const ReqURL = createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest<Request>(); console.log(data); return request.url; },);import { Controller, Get, Post, Body, Patch, Param, Delete, Inject, UseGuards, SetMetadata,} from "@nestjs/common";import { UserService } from "./user.service";import { ReqURL, Role } from "src/role.decorator";
@Controller("user")export class UserController { constructor(private readonly userService: UserService) {}
@Get() @Role("admin") findAll(@ReqURL("12") url: string) { console.log(url); return this.userService.findAll(); }}File upload
Section titled “File upload”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { NestExpressApplication } from "@nestjs/platform-express";import { join } from "path";
async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.enableCors();
// 配置静态资源访问 app.useStaticAssets(join(__dirname, "uploads"), { prefix: "/images", });
await app.listen(process.env.PORT ?? 3000);}bootstrap();import { Module } from "@nestjs/common";import { FileService } from "./file.service";import { FileController } from "./file.controller";import { MulterModule } from "@nestjs/platform-express";import { diskStorage } from "multer";import { extname, join } from "path";
@Module({ imports: [ MulterModule.register({ storage: diskStorage({ destination: join(__dirname, "../uploads"), filename: (_, file, callback) => { const fileName = `${new Date().getTime() + extname(file.originalname)}`; callback(null, fileName); }, }), }), ], controllers: [FileController], providers: [FileService],})export class FileModule {}import { Controller, Post, UseInterceptors, UploadedFile, UploadedFiles, Get, Res,} from "@nestjs/common";import { FileService } from "./file.service";import { FileFieldsInterceptor, FileInterceptor,} from "@nestjs/platform-express";import { join } from "path";import type { Response } from "express";import { zip } from "compressing";
@Controller("file")export class FileController { constructor(private readonly fileService: FileService) {}
@Post("upload") @UseInterceptors(FileInterceptor("file")) uploadFile(@UploadedFile() file: Express.Multer.File) { console.log(file); }
@Post("uploads") @UseInterceptors( FileFieldsInterceptor([ { name: "avatar", maxCount: 1 }, { name: "background", maxCount: 1 }, ]), ) uploadFiles( @UploadedFiles() files: { avatar?: Express.Multer.File[]; background?: Express.Multer.File[]; }, ) { console.log(files); }
@Get("download") downloadFile(@Res() res: Response) { const url = join(__dirname, "../images/1.png"); res.download(url); }
@Get("dl") async downloadFileWithStream(@Res() res: Response) { const url = join(__dirname, "../images/1.png"); const stream = new zip.Stream(); await stream.addEntry(url); res.setHeader("Content-Type", "application/octet-stream"); res.setHeader("Content-Disposition", 'attachment; filename="1.zip"'); stream.pipe(res); }}<script setup lang="ts">const useFetch = async (link: string) => { const res = await fetch(link).then((res) => res.arrayBuffer()); const blob = new Blob([res]); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "1.zip"; a.click(); URL.revokeObjectURL(url);};
const download = () => { useFetch("http://localhost:3000/file/dl");
// window.open('http://localhost:3000/file/download')};</script>
<template> <button @click="download">Download</button></template>
<style scoped></style>import { Injectable } from "@nestjs/common";import * as cheerio from "cheerio";import axios from "axios";import path from "path";import fs from "fs";
@Injectable()export class SpiderService { async findAll() { const urls: string[] = []; const baseURL = ""; const nextText = "下一页"; let index = 0;
const getData = async () => { const body = await axios .get(`https://exmple.com/${index ? "_" + index : ""}`) .then(async (res) => res.data);
const $ = cheerio.load(body);
const page = $(".pagination").eq(0).find("span");
const pageArray = page .map(function () { return $(this).text(); }) .toArray();
if (pageArray.includes(nextText)) { $(".content-area a .post-title").each(function () { urls.push(baseURL + $(this).attr("href")); }); index++; await getData(); } };
await getData(); this.downloadFile(urls);
return `This action returns all spider`; }
downloadFile(urls: string[]) { urls.forEach(async (url) => { const res = await axios .get(url, { responseType: "arraybuffer" }) .then((res) => res.data); const ws = fs.createWriteStream( path.join(__dirname, "../downloads/" + new Date().getTime() + ".png"), ); ws.write(res); ws.end(); }); }}OpenAPI
Section titled “OpenAPI”import { NestFactory } from "@nestjs/core";import { AppModule } from "./app.module";import { NestExpressApplication } from "@nestjs/platform-express";import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule);
const config = new DocumentBuilder() .addBearerAuth() .setTitle("Users example") .setDescription("The users API description") .setVersion("1.0") .build(); const documentFactory = () => SwaggerModule.createDocument(app, config); SwaggerModule.setup("/api-docs", app, documentFactory);
await app.listen(process.env.PORT ?? 3000);}bootstrap();import { Controller, Get, Post, Body, Patch, Param, Delete, Inject, UseGuards, SetMetadata,} from "@nestjs/common";import { UserService } from "./user.service";import { ApiBearerAuth, ApiOperation, ApiParam, ApiQuery, ApiTags,} from "@nestjs/swagger";
@ApiBearerAuth()@ApiTags("user")@Controller("user")export class UserController { constructor(private readonly userService: UserService) {}
@Post() @ApiOperation({ summary: "Create user" }) create(@Body() createUserDto: CreateUserDto) { return this.userService.create(createUserDto); }
@Get() @ApiQuery({ name: "page", description: "page list", }) findAll() { return this.userService.findAll(); }
@Get(":id") @ApiParam({ name: "id", description: "user id", required: true, type: "string", example: "11", }) findOne(@Param("id") id: string) { return this.userService.findOne(+id); }}import { ApiProperty } from "@nestjs/swagger";
export class CreateUserDto { @ApiProperty({ example: "login_name" }) account: string;
@ApiProperty({ example: "password" }) password: string;}