From harness-claude
Validates and transforms request data in NestJS using global ValidationPipe, built-in Parse pipes, DTOs with class-validator decorators, and custom PipeTransform pipes. For request body validation, param conversion, and mass-assignment protection.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Validate and transform request data with PipeTransform, ValidationPipe, and custom pipes
Validates NestJS request payloads using class-validator, class-transformer, and DTOs. Supports nested objects, partial updates via PartialType, and Swagger/OpenAPI docs.
Provides NestJS patterns for scalable Node.js/TypeScript backends: modular architecture, dependency injection, DTO validation, repositories, and events.
Provides NestJS patterns for modules, controllers, providers, DTO validation, guards, interceptors, config, and production TypeScript backends. Useful for structuring APIs, adding validation, and database integrations.
Share bugs, ideas, or general feedback.
Validate and transform request data with PipeTransform, ValidationPipe, and custom pipes
main.ts (recommended for most applications):app.useGlobalPipes(
new ValidationPipe({
whitelist: true, // strip properties not in DTO
forbidNonWhitelisted: true, // throw on extra properties
transform: true, // auto-transform payload to DTO class instance
transformOptions: { enableImplicitConversion: true },
})
);
@Get(':id')
findOne(@Param('id', ParseUUIDPipe) id: string) { ... }
@Get(':page')
list(@Query('page', ParseIntPipe) page: number) { ... }
@Param('status', new ParseEnumPipe(UserStatus)) status: UserStatus
import { IsEmail, IsString, MinLength, IsOptional } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@MinLength(8)
password: string;
@IsOptional()
@IsString()
displayName?: string;
}
PipeTransform<T, R>:@Injectable()
export class TrimPipe implements PipeTransform<string, string> {
transform(value: string): string {
if (typeof value !== 'string') return value;
return value.trim();
}
}
Apply custom pipes at the parameter level: @Body('name', TrimPipe) name: string.
For pipes that may fail (e.g., parsing), throw BadRequestException rather than returning null.
Pipes serve two roles: validation (throw if invalid) and transformation (convert to the expected type). Both happen before the handler executes.
whitelist: true behavior: ValidationPipe strips any property on the incoming JSON that has no corresponding decorator in the DTO. This prevents mass-assignment attacks where clients send unexpected fields (e.g., isAdmin: true). forbidNonWhitelisted: true goes further and throws a 400 if any extra property is present.
transform: true: Without this, @Body() dto: CreateUserDto gives you a plain object, not a CreateUserDto instance. With it, NestJS runs class-transformer's plainToInstance automatically so you get a proper class instance and @Type() decorators work correctly.
Class-validator integration: All class-validator decorators (@IsEmail(), @IsUUID(), @IsEnum(), @Min(), @Max(), etc.) work with ValidationPipe. Nested DTOs require @ValidateNested() combined with @Type(() => NestedDto).
Scope: Pipes can be applied at four levels (most specific wins):
app.useGlobalPipes()@UsePipes()@UsePipes()@Param('id', ParseUUIDPipe)Async pipes: transform() can return Promise<R>. This enables async validation (e.g., checking a database for uniqueness), though this is better done at the service layer.