From 9e6e36e115c3c77cf2fe7ef7810bb5a40312b49a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E7=A7=8B=E6=97=AD?= Date: Wed, 15 Feb 2023 20:44:32 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20add=20class-validator=20&=20class-t?= =?UTF-8?q?ransformer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 ++ pnpm-lock.yaml | 51 ++++++++++++++++++++++++++------ src/main.ts | 4 +++ src/users/dto/create-user.dto.ts | 24 +++++++++++++++ src/users/users.controller.ts | 5 ++-- 5 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 src/users/dto/create-user.dto.ts diff --git a/package.json b/package.json index f7b3e3d..c2e1f0b 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,8 @@ "@nestjs/mapped-types": "^1.2.2", "@nestjs/platform-express": "^9.0.0", "@prisma/client": "^4.10.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", "nestjs-prisma": "^0.20.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a33748..b717304 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,8 @@ specifiers: '@types/node': 18.11.18 '@typescript-eslint/eslint-plugin': ^5.0.0 '@typescript-eslint/parser': ^5.0.0 + class-transformer: ^0.5.1 + class-validator: ^0.14.0 eslint: ^8.0.1 eslint-config-prettier: ^8.3.0 eslint-plugin-prettier: ^4.0.0 @@ -31,12 +33,14 @@ specifiers: webpack: ^5.75.0 dependencies: - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i '@nestjs/config': 2.3.1_jrq2rdgfp2sx67wmylmrqliwxe '@nestjs/core': 9.3.9_q6agyr4hwia55oswpsa7zjxcpm - '@nestjs/mapped-types': 1.2.2_ilxajbd2e536h4oohar7aljlry + '@nestjs/mapped-types': 1.2.2_sm5si6oczf3vcbfl6qa276t67m '@nestjs/platform-express': 9.3.9_77foi4w27ghy47yutmnzv7krjy '@prisma/client': 4.10.1_prisma@4.10.1 + class-transformer: 0.5.1 + class-validator: 0.14.0 nestjs-prisma: 0.20.0_uhhmeuf5jto6tk72f36tv2cdfe reflect-metadata: 0.1.13 rxjs: 7.8.0 @@ -354,7 +358,7 @@ packages: - webpack-cli dev: true - /@nestjs/common/9.3.9_mnr6j2del53muneqly5h4y27ai: + /@nestjs/common/9.3.9_welcnyot5bzd5wa2aovbkxpi4i: resolution: {integrity: sha512-GshTD9Xz+wD2em6NyzU4NXw5IXMUmapgDgD+iuj6XL0258hvDwODmNk37mBBnZvTZlqER+krvIUKnS34etqF/A==} peerDependencies: cache-manager: <=5 @@ -370,6 +374,8 @@ packages: class-validator: optional: true dependencies: + class-transformer: 0.5.1 + class-validator: 0.14.0 iterare: 1.2.1 reflect-metadata: 0.1.13 rxjs: 7.8.0 @@ -384,7 +390,7 @@ packages: reflect-metadata: ^0.1.13 rxjs: ^6.0.0 || ^7.2.0 dependencies: - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i dotenv: 16.0.3 dotenv-expand: 10.0.0 lodash: 4.17.21 @@ -411,7 +417,7 @@ packages: '@nestjs/websockets': optional: true dependencies: - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i '@nestjs/platform-express': 9.3.9_77foi4w27ghy47yutmnzv7krjy '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 @@ -425,7 +431,7 @@ packages: - encoding dev: false - /@nestjs/mapped-types/1.2.2_ilxajbd2e536h4oohar7aljlry: + /@nestjs/mapped-types/1.2.2_sm5si6oczf3vcbfl6qa276t67m: resolution: {integrity: sha512-3dHxLXs3M0GPiriAcCFFJQHoDFUuzTD5w6JDhE7TyfT89YKpe6tcCCIqOZWdXmt9AZjjK30RkHRSFF+QEnWFQg==} peerDependencies: '@nestjs/common': ^7.0.8 || ^8.0.0 || ^9.0.0 @@ -438,7 +444,9 @@ packages: class-validator: optional: true dependencies: - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i + class-transformer: 0.5.1 + class-validator: 0.14.0 reflect-metadata: 0.1.13 dev: false @@ -448,7 +456,7 @@ packages: '@nestjs/common': ^9.0.0 '@nestjs/core': ^9.0.0 dependencies: - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i '@nestjs/core': 9.3.9_q6agyr4hwia55oswpsa7zjxcpm body-parser: 1.20.1 cors: 2.8.5 @@ -654,6 +662,10 @@ packages: '@types/node': 18.11.18 dev: true + /@types/validator/13.7.12: + resolution: {integrity: sha512-YVtyAPqpefU+Mm/qqnOANW6IkqKpCSrarcyV269C8MA8Ux0dbkEuQwM/4CjL47kVEM2LgBef/ETfkH+c6+moFA==} + dev: false + /@typescript-eslint/eslint-plugin/5.52.0_6cfvjsbua5ptj65675bqcn6oza: resolution: {integrity: sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1214,6 +1226,18 @@ packages: engines: {node: '>=6.0'} dev: true + /class-transformer/0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + dev: false + + /class-validator/0.14.0: + resolution: {integrity: sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==} + dependencies: + '@types/validator': 13.7.12 + libphonenumber-js: 1.10.19 + validator: 13.9.0 + dev: false + /clean-stack/2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -2284,6 +2308,10 @@ packages: type-check: 0.4.0 dev: true + /libphonenumber-js/1.10.19: + resolution: {integrity: sha512-MDZ1zLIkfSDZV5xBta3nuvbEOlsnKCPe4z5r3hyup/AXveevkl9A1eSWmLhd2FX4k7pJDe4MrLeQsux0HI/VWg==} + dev: false + /lilconfig/2.0.6: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} @@ -2541,7 +2569,7 @@ packages: dependencies: '@angular-devkit/core': 13.3.10 '@angular-devkit/schematics': 13.3.10 - '@nestjs/common': 9.3.9_mnr6j2del53muneqly5h4y27ai + '@nestjs/common': 9.3.9_welcnyot5bzd5wa2aovbkxpi4i '@prisma/client': 4.10.1_prisma@4.10.1 '@schematics/angular': 13.3.10 prisma: 4.10.1 @@ -3477,6 +3505,11 @@ packages: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true + /validator/13.9.0: + resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} + engines: {node: '>= 0.10'} + dev: false + /vary/1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} diff --git a/src/main.ts b/src/main.ts index c4fbda2..531ce57 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ import { HttpAdapterHost, NestFactory } from '@nestjs/core' +import { ValidationPipe } from '@nestjs/common' import { ConfigService } from '@nestjs/config' import { PrismaClientExceptionFilter, PrismaService } from 'nestjs-prisma' import { AppModule } from './app.module' @@ -6,6 +7,9 @@ import { AppModule } from './app.module' async function bootstrap() { const app = await NestFactory.create(AppModule) + // Validation + app.useGlobalPipes(new ValidationPipe({ whitelist: true })) + // enable shutdown hook const prismaService = app.get(PrismaService) await prismaService.enableShutdownHooks(app) diff --git a/src/users/dto/create-user.dto.ts b/src/users/dto/create-user.dto.ts new file mode 100644 index 0000000..15162b4 --- /dev/null +++ b/src/users/dto/create-user.dto.ts @@ -0,0 +1,24 @@ +import { + IsNotEmpty, + IsOptional, + IsString, + Length, + IsEmail, + IsStrongPassword, +} from 'class-validator' + +export class CreateUserDto { + @IsNotEmpty() + @IsEmail() + email: string + + @IsOptional() + @IsString() + @Length(5, 20) + username?: string + + @IsString() + @IsNotEmpty() + @IsStrongPassword() + password: string +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 3a820d4..b14b34f 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -1,5 +1,6 @@ import { Controller, Get, Post, Body, Param } from '@nestjs/common' import { UsersService } from './users.service' +import { CreateUserDto } from './dto/create-user.dto' @Controller() export class UsersController { @@ -16,9 +17,7 @@ export class UsersController { } @Post('users') - async createUser( - @Body() userData: { email: string; password: string; username?: string }, - ) { + async createUser(@Body() userData: CreateUserDto) { return this.userService.createUser(userData) } }