feat: Add class-transformer and class-validator packages
- Added "@nestjs/mapped-types" package to package.json - Added "class-transformer" and "class-validator" packages to package.json - Imported ValidationPipe from "@nestjs/common" in main.ts and added it as a global pipe - Added validation decorators to CreateUserInput, SetUserPasswordInput, and UpdateUserInput classes - Created UserController with create, findAll, and removeUser methods - Updated UserEntity class with @Exclude decorator for password field - Updated UserModule to include UserController - Updated UserService to use class-transformer for mapping Prisma entities to UserEntity class - Updated UserService to return UserEntity instances instead of Prisma entities - Updated UserService to handle NotFoundException for setPassword and remove methods
This commit is contained in:
parent
38105c3d43
commit
b40249fdfb
@ -18,10 +18,13 @@
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/mapped-types": "^2.0.6",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-express": "^10.4.11",
|
||||
"@prisma/client": "5.22.0",
|
||||
"axios": "^1.7.7",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"passport": "^0.7.0",
|
||||
"passport-discord": "^0.1.4",
|
||||
"passport-jwt": "^4.0.1",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { NestFactory } from "@nestjs/core";
|
||||
import { AppModule } from "./app.module";
|
||||
import { ValidationPipe } from "@nestjs/common";
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
@ -8,6 +9,8 @@ async function bootstrap() {
|
||||
origin: "*",
|
||||
});
|
||||
|
||||
app.useGlobalPipes(new ValidationPipe());
|
||||
|
||||
await app.listen(process.env.PORT ?? 3000, "0.0.0.0");
|
||||
}
|
||||
bootstrap();
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { IsBoolean, IsString } from "class-validator";
|
||||
|
||||
export class CreateUserInput {
|
||||
@IsString()
|
||||
username: string;
|
||||
|
||||
@IsBoolean()
|
||||
isAdmin: boolean;
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { IsString } from "class-validator";
|
||||
|
||||
export class SetUserPasswordInput {
|
||||
@IsString()
|
||||
id: string;
|
||||
|
||||
@IsString()
|
||||
password: string;
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
import { PartialType } from "@nestjs/mapped-types";
|
||||
import { IsString } from "class-validator";
|
||||
|
||||
import { CreateUserInput } from "./create-user.input";
|
||||
|
||||
export class UpdateUserInput extends CreateUserInput {
|
||||
export class UpdateUserInput extends PartialType(CreateUserInput) {
|
||||
@IsString()
|
||||
id: string;
|
||||
|
||||
@IsString()
|
||||
username: string;
|
||||
}
|
||||
|
26
src/user/user.controller.ts
Normal file
26
src/user/user.controller.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Body, Controller, Delete, Get, Param, Post, UseGuards } from "@nestjs/common";
|
||||
import { AuthGuard } from "@nestjs/passport";
|
||||
|
||||
import { CreateUserInput } from "./dto/create-user.input";
|
||||
import { UserService } from "./user.service";
|
||||
|
||||
@Controller("user")
|
||||
@UseGuards(AuthGuard("jwt"))
|
||||
export class UserController {
|
||||
constructor(private readonly userService: UserService) {}
|
||||
|
||||
@Post()
|
||||
create(@Body() createUserInput: CreateUserInput) {
|
||||
return this.userService.create(createUserInput);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.userService.findAll();
|
||||
}
|
||||
|
||||
@Delete(":id")
|
||||
removeUser(@Param("id") id: string) {
|
||||
return this.userService.remove(id);
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
import { Exclude } from "class-transformer";
|
||||
|
||||
export class User {
|
||||
export class UserEntity {
|
||||
id: string;
|
||||
|
||||
|
||||
username: string;
|
||||
|
||||
isAdmin: boolean;
|
||||
|
||||
@Exclude()
|
||||
password: string;
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ import { Module } from "@nestjs/common";
|
||||
import { UserService } from "./user.service";
|
||||
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { UserController } from './user.controller';
|
||||
|
||||
@Module({
|
||||
providers: [UserService, PrismaService]
|
||||
providers: [UserService, PrismaService],
|
||||
controllers: [UserController]
|
||||
})
|
||||
export class UserModule {}
|
||||
|
@ -1,48 +1,77 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||
import { plainToClass } from "class-transformer";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
|
||||
import { CreateUserInput } from "./dto/create-user.input";
|
||||
import { UpdateUserInput } from "./dto/update-user.input";
|
||||
import { SetUserPasswordInput } from "./dto/setpassword-user.input";
|
||||
import { UserEntity } from "./user.entity";
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async create(createUserInput: CreateUserInput) {
|
||||
return await this.prisma.user.create({
|
||||
const user = await this.prisma.user.create({
|
||||
data: {
|
||||
username: createUserInput.username,
|
||||
isAdmin: createUserInput.isAdmin,
|
||||
},
|
||||
});
|
||||
|
||||
return plainToClass(UserEntity, user);
|
||||
}
|
||||
|
||||
async update(updateUserInput: UpdateUserInput) {
|
||||
return await this.prisma.user.update({
|
||||
const user = await this.prisma.user.update({
|
||||
where: { id: updateUserInput.id },
|
||||
data: {
|
||||
username: updateUserInput.username,
|
||||
isAdmin: updateUserInput.isAdmin,
|
||||
},
|
||||
});
|
||||
|
||||
return plainToClass(UserEntity, user);
|
||||
}
|
||||
|
||||
async setPassword(setUserPasswordInput: SetUserPasswordInput) {
|
||||
return await this.prisma.user.update({
|
||||
const exist = await this.prisma.user.findUnique({
|
||||
where: { id: setUserPasswordInput.id },
|
||||
});
|
||||
if (!exist) throw new NotFoundException("User not found");
|
||||
|
||||
const user = await this.prisma.user.update({
|
||||
where: { id: setUserPasswordInput.id },
|
||||
data: {
|
||||
password: setUserPasswordInput.password,
|
||||
},
|
||||
});
|
||||
|
||||
return plainToClass(UserEntity, user);
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
return await this.prisma.user.findMany();
|
||||
const users = await this.prisma.user.findMany();
|
||||
|
||||
return users.map((user) => plainToClass(UserEntity, user));
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
return await this.prisma.user.findUnique({
|
||||
const user = await this.prisma.user.findUnique({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
return plainToClass(UserEntity, user);
|
||||
}
|
||||
|
||||
async remove(id: string) {
|
||||
const exist = await this.prisma.user.findUnique({ where: { id } });
|
||||
if (!exist) throw new NotFoundException("User not found");
|
||||
|
||||
const user = await this.prisma.user.delete({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
return plainToClass(UserEntity, user);
|
||||
}
|
||||
}
|
||||
|
34
yarn.lock
34
yarn.lock
@ -284,6 +284,11 @@
|
||||
"@types/jsonwebtoken" "9.0.5"
|
||||
jsonwebtoken "9.0.2"
|
||||
|
||||
"@nestjs/mapped-types@^2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.6.tgz#d2d8523709fd5d872a9b9e0c38162746e2a7f44e"
|
||||
integrity sha512-84ze+CPfp1OWdpRi1/lOu59hOhTz38eVzJvRKrg9ykRFwDz+XleKfMsG0gUqNZYFa6v53XYzeD+xItt8uDW7NQ==
|
||||
|
||||
"@nestjs/passport@^10.0.3":
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/passport/-/passport-10.0.3.tgz#26ec5b2167d364e04962c115fcef80d10e185367"
|
||||
@ -563,6 +568,11 @@
|
||||
"@types/node" "*"
|
||||
"@types/send" "*"
|
||||
|
||||
"@types/validator@^13.11.8":
|
||||
version "13.12.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.2.tgz#760329e756e18a4aab82fc502b51ebdfebbe49f5"
|
||||
integrity sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^8.0.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz#ac56825bcdf3b392fc76a94b1315d4a162f201a6"
|
||||
@ -1091,6 +1101,20 @@ chrome-trace-event@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b"
|
||||
integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==
|
||||
|
||||
class-transformer@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336"
|
||||
integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==
|
||||
|
||||
class-validator@^0.14.1:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.1.tgz#ff2411ed8134e9d76acfeb14872884448be98110"
|
||||
integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==
|
||||
dependencies:
|
||||
"@types/validator" "^13.11.8"
|
||||
libphonenumber-js "^1.10.53"
|
||||
validator "^13.9.0"
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||
@ -2142,6 +2166,11 @@ levn@^0.4.1:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
libphonenumber-js@^1.10.53:
|
||||
version "1.11.15"
|
||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.11.15.tgz#0947ba02208cf6c44fdf3b07e097a98b3ec945f4"
|
||||
integrity sha512-M7+rtYi9l5RvMmHyjyoF3BHHUpXTYdJ0PezZGHNs0GyW1lO+K7jxlXpbdIb7a56h0nqLYdjIw+E+z0ciGaJP7g==
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
@ -3214,6 +3243,11 @@ v8-compile-cache-lib@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
|
||||
|
||||
validator@^13.9.0:
|
||||
version "13.12.0"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f"
|
||||
integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==
|
||||
|
||||
vary@^1, vary@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
|
Loading…
Reference in New Issue
Block a user