Lightweight NestJS decorators for validating values against TypeORM entities.
This package provides several decorators (more to come):
| Decorator | Description |
|---|---|
@ExistsIn |
Ensures a value exists in a specified entity/table column. |
@UniqueIn |
Ensures a value is unique in a specified entity/table column. |
It integrates with TypeORM DataSource instances, enabling database-aware validation in DTOs.
- Works with TypeORM entity classes or table name strings.
- Supports multiple (named) TypeORM DataSource registrations.
- Supports class-validator options (for example
eachfor array validation, ormessagefor custom message). - Minimal runtime dependency surface — relies on TypeORM and class-validator as peer dependencies.
Install the package:
npm install @rotyro-tools/nestjs-typeorm-validatoryarn add @rotyro-tools/nestjs-typeorm-validatorpnpm add @rotyro-tools/nestjs-typeorm-validatorbun add @rotyro-tools/nestjs-typeorm-validatorThis package declares the following peer dependencies that consumers must install at compatible versions:
Install them:
npm install --save class-validator typeormyarn add class-validator typeormpnpm add class-validator typeormbun add class-validator typeorm- Register one or more TypeORM DataSources to be used by the validators:
import { registerDataSourceForValidation } from '@rotyro-tools/nestjs-typeorm-validator';
import { DataSource } from 'typeorm';
const dataSource = new DataSource({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'user',
password: 'pass',
database: 'db',
entities: [
/* ... */
],
synchronize: false,
});
// If you initialize the DataSource yourself, that's fine. If you don't, registerDataSourceForValidation will attempt to initialize it for you.
await dataSource.initialize();
// Register your DataSource
registerDataSourceForValidation(dataSource); // Registers as 'default'
// Second 'replica' DataSource
const replicaDataSource = new DataSource({
type: 'mysql',
host: 'replica-host',
port: 3306,
username: 'replica_user',
password: 'replica_pass',
database: 'db_replica',
entities: [
/* ... */
],
synchronize: false,
});
// Optionally initialize the replica DataSource as well
await replicaDataSource.initialize();
// Register your DataSource
registerDataSourceForValidation(replicaDataSource, 'replica');- Use decorators in your DTOs:
import { ExistsIn, UniqueIn } from '@rotyro-tools/nestjs-typeorm-validator';
import { User } from '@/modules/users/entities/user.entity';
class CreatePostDto {
// Ensure the given authorId exists in the User entity's id column
// in the 'default' DataSource
@ExistsIn(User, 'id', null, { message: 'Author not found' })
authorId: number;
// Ensure the title is unique in the posts table (using a table name)
// in the 'replica' DataSource
@UniqueIn('post', 'title', 'replica', { message: 'Title already taken' })
title: string;
}Checking existence (minimal setup):
import { ExistsIn } from '@rotyro-tools/nestjs-typeorm-validator';
class CreateCommentDto {
@ExistsIn('user', 'id')
userId: number;
}Unique constraint (entity usage and custom message):
import { UniqueIn } from '@rotyro-tools/nestjs-typeorm-validator';
import { User } from '@/modules/users/entities/user.entity';
class RegisterUserDto {
@UniqueIn(User, 'email', null, { message: 'Email already in use' })
email: string;
}Validating arrays:
import { ExistsIn } from '@rotyro-tools/nestjs-typeorm-validator';
class BulkCreateDto {
@ExistsIn('tag', 'name', 'replica', {
each: true,
message: 'Tag does not exist',
})
tagNames: string[];
}Install dependencies:
npm installBuild:
npm run buildLint:
npm run lintFormat:
npm run formatRun tests:
npm run testCommit (with Commitizen):
npm run cm