add validators

This commit is contained in:
Sergey Krylov 2025-06-05 06:08:29 +03:00
parent 930068c7e6
commit 8d62280efb
7 changed files with 106 additions and 3 deletions

View File

@ -24,6 +24,8 @@
"@nestjs/core": "^11.0.1",
"@nestjs/mapped-types": "*",
"@nestjs/platform-express": "^11.0.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1"
},

View File

@ -1,8 +1,10 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

View File

@ -0,0 +1,24 @@
import { registerDecorator, ValidatorOptions } from 'class-validator';
export function StartsWiths(
prefix: string,
validatorOption?: ValidatorOptions,
) {
return (obj: object, propertyName: string) => {
registerDecorator({
name: 'startsWith',
target: obj.constructor,
propertyName,
options: validatorOption,
validator: {
validate(value: any): Promise<boolean> | boolean {
console.log('value', value);
return typeof value === 'string' && value.startsWith(prefix);
},
defaultMessage(): string {
return `Should start with "${prefix}"`;
},
},
});
};
}

View File

@ -1,3 +1,39 @@
export class CreateTaskDto {
title: string;
import {
IsArray,
IsEnum,
IsInt,
IsNotEmpty,
IsOptional,
IsPositive,
IsString,
Length,
} from 'class-validator';
import { StartsWiths } from '../docorators/start-with.decorator';
export enum TaskTag {
WORK = 'work',
STUDY = 'study',
HOME = 'home',
}
export class CreateTaskDto {
@IsString()
@IsNotEmpty()
@StartsWiths('task')
@Length(2, 10)
title: string;
@IsString()
@IsOptional()
description: string;
@IsInt({})
@IsOptional()
@IsPositive()
priority: number;
@IsArray()
@IsEnum(TaskTag, { each: true })
@IsOptional()
tags: TaskTag[];
}

View File

@ -1,4 +1,11 @@
import { IsBoolean, IsNotEmpty, IsString, Length } from 'class-validator';
export class UpdateTaskDto {
@IsString({ message: 'Должно быть строкой' })
@IsNotEmpty({ message: 'Не должно быть пустым' })
@Length(2, 40, { message: 'Должно быть от 2 до 40 символов' })
title: string;
@IsBoolean({ message: 'Должно быть булевым выражением' })
isCompleted: boolean;
}

View File

@ -32,11 +32,14 @@ export class TaskService {
}
create(dto: CreateTaskDto) {
const { title } = dto;
const { title, description, priority, tags } = dto;
const newTask = {
id: this.tasks.length + 1,
title,
isCompleted: false,
description,
priority,
tags,
};
this.tasks.push(newTask);

View File

@ -1462,6 +1462,11 @@
"@types/methods" "^1.1.4"
"@types/superagent" "^8.1.0"
"@types/validator@^13.11.8":
version "13.15.1"
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.15.1.tgz#52f3617eb5ba30dd0018380c64568440d0b4de0a"
integrity sha512-9gG6ogYcoI2mCMLdcO0NYI0AYrbxIjv0MDmy/5Ywo6CpWWrqYayc+mmgxRsCgtcGJm9BSbXkMsmxGah1iGHAAQ==
"@types/yargs-parser@*":
version "21.0.3"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15"
@ -2264,6 +2269,20 @@ cjs-module-lexer@^1.0.0:
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d"
integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==
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.2:
version "0.14.2"
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.2.tgz#a3de95edd26b703e89c151a2023d3c115030340d"
integrity sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==
dependencies:
"@types/validator" "^13.11.8"
libphonenumber-js "^1.11.1"
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"
@ -4051,6 +4070,11 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
libphonenumber-js@^1.11.1:
version "1.12.8"
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.8.tgz#20e5b57f24e60359d795e2fa2ee185776331e34f"
integrity sha512-f1KakiQJa9tdc7w1phC2ST+DyxWimy9c3g3yeF+84QtEanJr2K77wAmBPP22riU05xldniHsvXuflnLZ4oysqA==
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"
@ -5527,6 +5551,11 @@ v8-to-istanbul@^9.0.1:
"@types/istanbul-lib-coverage" "^2.0.1"
convert-source-map "^2.0.0"
validator@^13.9.0:
version "13.15.15"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.15.tgz#246594be5671dc09daa35caec5689fcd18c6e7e4"
integrity sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==
vary@^1, vary@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"