npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@slaega/db-validation

v0.0.3

Published

A package for validating database rules in NestJS applications. before service execution.

Readme

@slaega/db-validation

🇫🇷 Version française

@slaega/db-validation is a NestJS validation library that supports multiple ORMs (Prisma, TypeORM, MicroORM, Sequelize). It allows you to declare common database validations through a unified builder and integrate them into your services via decorators with result retrieval.


🚀 Features

  • Multi-ORM Support: Compatible with Prisma, TypeORM, MicroORM, and Sequelize
  • Unified Builder: A single builder with ORM-specific methods
  • Smart Validations:
    • exists (404 Not Found) - Returns the entity if found
    • ensureExists (400 Bad Request) - Returns the entity if found
    • unique (409 Conflict)
    • ensureNotExists (400 Bad Request)
    • Count validations: ensureCountAtLeast, ensureCountAtMost, ensureCountEquals
  • Decorator with Results: Retrieve validated entities directly in your methods
  • Type-safe: Full TypeScript support for all ORMs

📦 Installation

yarn add @slaega/db-validation
# or
npm install @slaega/db-validation

Required Dependencies

  1. NestJS Dependencies (required in all cases)
yarn add @nestjs/common @nestjs/core reflect-metadata
  1. ORM-specific Dependencies

For Prisma

yarn add @prisma/client

For TypeORM

yarn add @nestjs/typeorm typeorm

For MikroORM

yarn add @mikro-orm/core @mikro-orm/nestjs

For Sequelize

yarn add @nestjs/sequelize sequelize sequelize-typescript

Module Configuration

With Prisma

import { Module } from '@nestjs/common';
import { DbValidationModule } from '@slaega/db-validation';
import { PrismaModule } from './prisma/prisma.module';
import { PrismaService } from './prisma/prisma.service';

@Module({
  imports: [
    PrismaModule,
    DbValidationModule.registerAsync({
      imports: [PrismaModule],
      useFactory: (prisma: PrismaService) => ({
        adapter: new PrismaAdapter(prisma)
      }),
      inject: [PrismaService],
    }),
  ],
})
export class AppModule {}

With TypeORM

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DbValidationModule } from '@slaega/db-validation';
import { DataSource } from 'typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      // your TypeORM config
    }),
    DbValidationModule.forRoot({
      useFactory: (dataSource: DataSource) => ({
        adapter: new TypeORMAdapter(dataSource)
      }),
      inject: [DataSource]
    })
  ]
})
export class AppModule {}

With MikroORM

import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { DbValidationModule } from '@slaega/db-validation';
import { MikroORM } from '@mikro-orm/core';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      // your MikroORM config
    }),
    DbValidationModule.forRoot({
      useFactory: (orm: MikroORM) => ({
        adapter: new MikroOrmAdapter(orm)
      }),
      inject: [MikroORM]
    })
  ]
})
export class AppModule {}

With Sequelize

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { DbValidationModule } from '@slaega/db-validation';
import { Sequelize } from 'sequelize-typescript';

@Module({
  imports: [
    SequelizeModule.forRoot({
      // your Sequelize config
    }),
    DbValidationModule.forRoot({
      useFactory: (sequelize: Sequelize) => ({
        adapter: new SequelizeAdapter(sequelize)
      }),
      inject: [Sequelize]
    })
  ]
})
export class AppModule {}

⚙️ Usage

1. Using the Builder

The builder can be used directly or in a validation class. Here's the syntax for each ORM:

With Prisma

import { ValidationBuilder } from '@slaega/db-validation';

// Using model names as strings
const builder = ValidationBuilder
  .forPrisma()
  .ensureExists('User', { id: 1 })
  .unique('Post', { title: 'My title' });

With TypeORM

import { ValidationBuilder } from '@slaega/db-validation';
import { User } from './entities/user.entity';
import { Post } from './entities/post.entity';

// Using Entity classes
const builder = ValidationBuilder
  .forTypeorm()
  .ensureExists(User, { id: 1 })
  .unique(Post, { title: 'My title' });

With MikroORM

import { ValidationBuilder } from '@slaega/db-validation';
import { User } from './entities/user.entity';
import { Post } from './entities/post.entity';

// Using Entity classes
const builder = ValidationBuilder
  .forMikroOrm()
  .ensureExists(User, { id: 1 })
  .unique(Post, { title: 'My title' });

With Sequelize

import { ValidationBuilder } from '@slaega/db-validation';
import { User } from './models/user.model';
import { Post } from './models/post.model';

// Using Sequelize models
const builder = ValidationBuilder
  .forSequelize()
  .ensureExists(User, { id: 1 })
  .unique(Post, { title: 'My title' });

2. Organization with Validation Classes

For better code organization and easier mapping with the @UseDbValidation decorator, create a validation class per service. Each class contains rules for the corresponding service methods:

import { ValidationBuilder } from '@slaega/db-validation';

// With Prisma

// post.validation-rules.ts
export class PostValidationRules {
  // Rule for PostService.create
  create(email: string, input: CreatePostDto) {
    return ValidationBuilder
      .forPrisma()
      .ensureExists('Author', { email }, {
        message: 'Author not found',
        code: 'AUTHOR_NOT_FOUND'
      })
      .ensureNotExists('Post', { title: input.title }, {
        message: 'Title already exists',
        code: 'TITLE_DUPLICATE'
      });
  }
}

// 2. Using in service with result retrieval
@Injectable()
export class PostService {
  constructor(
    private readonly repo: PostRepository,
    private readonly dbValidationService: DbValidationService, // The attribute name doesn't matter
  ) {}

  // Note: The decorator automatically detects DbValidationService in the service
  // If you extend or modify DbValidationService, you must specify the getter:
  // @UseDbValidation(PostValidationRules, 'create', (self) => self.dbValidationService)
  //
  // Otherwise, automatic detection is sufficient:

  @UseDbValidation(PostValidationRules, 'create')
  async createPost(
    email: string,
    input: CreatePostDto,
    options?: ValidationOptions
  ) {
    // Results are in validation order
    const [authorResult, _] = options?.validationResult ?? [];

    // authorResult contains the Author object directly
    const author = authorResult;

    // You can use the validated author data
    return this.repo.create({
      ...input,
      authorId: author.id,
    });
  }
}

The validation flow:

  1. The decorator executes rules defined in PostValidationRules.create
  2. ensureExists checks the author and returns its data if found
  3. ensureNotExists verifies the title doesn't exist
  4. Results are passed to the method via options.validationResult
  5. You can use validated data (e.g., author) in your logic

3. Usage without Decorator

You can also use the validator directly:

const builder = new PostValidationRules().create(userId, input);
const results = await dbValidatorService.validate(builder);

// Access results
const [userResult] = results; 

console.log(userResult)

🧩 Validation Methods

HTTP Code Behavior

| Validation | Condition | HTTP Code | Exception | OK Result | |------------------|------------|-------------|---------------|------------------| | exists | Record found | 404 | NotFoundException | ✅ Found object | | ensureExists | Record found | 400 | BadRequestException | ✅ Found object | | unique | No duplicate | 409 | ConflictException | ✅ true | | ensureNotExists | No duplicate | 400 | BadRequestException | ✅ true | | ensureCountAtLeast| Count ≥ min | 400 | BadRequestException | ✅ { count: number } | | ensureCountAtMost| Count ≤ max | 400 | BadRequestException | ✅ { count: number } | | ensureCountEquals| Count = val | 400 | BadRequestException | ✅ { count: number } |

Result Examples

// For exists/ensureExists
const [userResult] = await service.validate(builder);
console.log(userResult); // { id: 1, email: '[email protected]', ... }

// For unique/ensureNotExists
const [uniqueResult] = await service.validate(builder);
console.log(uniqueResult); // true

// For count validations
const [countResult] = await service.validate(builder);
console.log(countResult); // { count: 5 }

🧪 Local Testing

  1. Clone & install

    git clone https://github.com/slaega/db-validation.git
    cd db-validation
    yarn install
  2. Build

    yarn build
  3. Link in a project

    yarn link
    cd ../your-app
    yarn link @slaega/db-validation
    yarn install
  4. Tests

    yarn test
    yarn test:watch

🤝 Contributing

  1. Fork the repo
  2. Create a branch (git checkout -b feature/my-feature)
  3. Commit your changes (git commit -m 'Add feature')
  4. Push to your branch (git push origin feature/my-feature)
  5. Open a Pull Request

📄 License

This project is under the MIT license. See LICENSE for more details.


Maintained by Slaega. Feel free to open issues on GitHub!