diff --git a/server/package-lock.json b/server/package-lock.json index e12f60e..c070ee7 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,10 +10,11 @@ "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", + "@nestjs/core": "^10.4.13", "@nestjs/platform-express": "^10.0.0", "@nestjs/swagger": "^8.1.0", "@prisma/client": "^6.0.1", + "class-validator": "^0.14.1", "prisma": "^6.0.1", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", @@ -22,7 +23,7 @@ "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", + "@nestjs/testing": "^10.4.13", "@types/express": "^5.0.0", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", @@ -1661,9 +1662,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.4.12", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.12.tgz", - "integrity": "sha512-2qENES1U0VxCOfW45jVIV7g38edcvuU5aaLpZWOhb3nzehdvmeYoovUe8LTTHFrLWsDVY1v9FPfEhFQGsZfopQ==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.13.tgz", + "integrity": "sha512-zivGEaq9tmwdeQi/RK0nUVdvhdIwcIsytBvEGTmDBFkmEnxEMp3T0Ia4BTFlTFrjLAb5D2cNUQZBZZj1vqfXtw==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -1719,9 +1720,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.4.12", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.12.tgz", - "integrity": "sha512-+m8BQas9mnY29Y6rZv8EUqIYwcta99/dTiGIUy48LB/+YoAyDTEHpsLd2+rpetk54niGgKJYclCZRUwRcjrYYA==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.13.tgz", + "integrity": "sha512-9Uar9t5NZebI9Y8P8B6OYTfj6p5DuUHM/nk2zGwbL3SLdnieP4O2K1DuePo3SWiYBStmPoTAlXyl6L2zDtrLjQ==", "license": "MIT", "dependencies": { "body-parser": "1.20.3", @@ -1797,9 +1798,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.4.12", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.12.tgz", - "integrity": "sha512-Q1ZpzmIqzem6Q9pBwT1qQRYE050HhvSh8U7AbdIavOHCI063GbXOy/erXEpUnE0o46mqT+y88Nn9NjTXAQt4nQ==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.13.tgz", + "integrity": "sha512-07PIDxZbr5sHq+1bHFtMqAyZuxvCqu041OU6pyCR3O76sspFizZg1oxIE2TYzPCKeCbNZavjQ2Zn1K9j+rnjvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2311,6 +2312,12 @@ "@types/superagent": "^8.1.0" } }, + "node_modules/@types/validator": { + "version": "13.12.2", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.2.tgz", + "integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==", + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -3463,6 +3470,25 @@ "dev": true, "license": "MIT" }, + "node_modules/class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/class-validator": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz", + "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==", + "license": "MIT", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.10.53", + "validator": "^13.9.0" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -6478,6 +6504,12 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.11.16", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.16.tgz", + "integrity": "sha512-Noyazmt0yOvnG0OeRY45Cd1ur8G7Z0HWVkuCuKe+yysGNxPQwBAODBQQ40j0AIagi9ZWurfmmZWNlpg4h4W+XQ==", + "license": "MIT" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -8973,6 +9005,15 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/server/package.json b/server/package.json index 5c7b375..0bbaf63 100644 --- a/server/package.json +++ b/server/package.json @@ -21,10 +21,11 @@ }, "dependencies": { "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", + "@nestjs/core": "^10.4.13", "@nestjs/platform-express": "^10.0.0", "@nestjs/swagger": "^8.1.0", "@prisma/client": "^6.0.1", + "class-validator": "^0.14.1", "prisma": "^6.0.1", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", @@ -33,7 +34,7 @@ "devDependencies": { "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", + "@nestjs/testing": "^10.4.13", "@types/express": "^5.0.0", "@types/jest": "^29.5.2", "@types/node": "^20.3.1", diff --git a/server/src/main.ts b/server/src/main.ts index eb36488..4e6e49a 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -1,9 +1,11 @@ import { NestFactory } from '@nestjs/core' import { AppModule } from './app.module' import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' +import { ValidationPipe } from '@nestjs/common' async function bootstrap() { const app = await NestFactory.create(AppModule) + app.useGlobalPipes(new ValidationPipe()) const config = new DocumentBuilder() .setTitle('Traintrape-moi') .setDescription('API permettant de stocker les données de Traintrape-moi') diff --git a/server/src/users/entities/user.entity.ts b/server/src/users/entities/user.entity.ts index 4502acc..6ca7039 100644 --- a/server/src/users/entities/user.entity.ts +++ b/server/src/users/entities/user.entity.ts @@ -1,5 +1,5 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { User } from "@prisma/client"; +import { ApiProperty } from "@nestjs/swagger" +import { User } from "@prisma/client" export class UserEntity implements User { @ApiProperty({description: "Identifiant unique"}) diff --git a/server/src/users/users.controller.ts b/server/src/users/users.controller.ts index f602df0..25f6d6f 100644 --- a/server/src/users/users.controller.ts +++ b/server/src/users/users.controller.ts @@ -1,6 +1,6 @@ -import { Controller, Get, Param } from '@nestjs/common' +import { Controller, Get, NotFoundException, Param, ParseIntPipe } from '@nestjs/common' import { UsersService } from './users.service' -import { ApiOkResponse } from '@nestjs/swagger' +import { ApiNotFoundResponse, ApiOkResponse } from '@nestjs/swagger' import { UserEntity } from './entities/user.entity' @Controller('users') @@ -9,13 +9,17 @@ export class UsersController { @Get() @ApiOkResponse({ type: UserEntity, isArray: true }) - findAll() { + async findAll() { return this.usersService.findAll() } @Get(':id') @ApiOkResponse({ type: UserEntity }) - findOne(@Param('id') id: string) { - return this.usersService.findOne(+id) + @ApiNotFoundResponse({ description: "Utilisateur⋅rice non trouvé⋅e" }) + async findOne(@Param('id', ParseIntPipe) id: number) { + const user = await this.usersService.findOne(id) + if (!user) + throw new NotFoundException(`L'utilisateur⋅rice avec l'identifiant ${id} n'existe pas`) + return user } } diff --git a/server/src/users/users.service.ts b/server/src/users/users.service.ts index 47720ec..72d8aa9 100644 --- a/server/src/users/users.service.ts +++ b/server/src/users/users.service.ts @@ -5,11 +5,11 @@ import { PrismaService } from 'src/prisma/prisma.service' export class UsersService { constructor(private prisma: PrismaService) {} - findAll() { - return this.prisma.user.findMany() + async findAll() { + return await this.prisma.user.findMany() } - findOne(id: number) { - return this.prisma.user.findUnique({ where: { id } }) + async findOne(id: number) { + return await this.prisma.user.findUnique({ where: { id } }) } }