NestboltNestbolt

@nestbolt/factory

Seeders

Populate your database with structured test data using ordered, composable seeder classes.

Seeders are classes that populate your database with test data in an organized, repeatable way. Each seeder defines what data to create and in what order.

Defining a Seeder

Implement the Seeder interface with a run() method that receives the FactoryService:

import type { Seeder, FactoryService } from "@nestbolt/factory";
import { UserFactory } from "../factories/user.factory";
import { PostFactory } from "../factories/post.factory";

export class DatabaseSeeder implements Seeder {
  order = 0;

  async run(factory: FactoryService): Promise<void> {
    await factory.use(UserFactory).count(10).create();
    await factory.use(UserFactory).state("admin").count(2).create();
    await factory.use(PostFactory).count(20).create();
  }
}

The Seeder Interface

interface Seeder {
  order?: number;
  run(factory: FactoryService): Promise<void>;
}
PropertyTypeDefaultDescription
ordernumber0Execution priority. Lower values run first.
run(factory: FactoryService) => Promise<void>--The seeding logic.

Ordering Seeders

Seeders are sorted by their order property before execution. Lower values run first:

export class UserSeeder implements Seeder {
  order = 0; // runs first

  async run(factory: FactoryService) {
    await factory.use(UserFactory).count(10).create();
  }
}

export class PostSeeder implements Seeder {
  order = 10; // runs second

  async run(factory: FactoryService) {
    await factory.use(PostFactory).count(20).create();
  }
}

export class CommentSeeder implements Seeder {
  order = 20; // runs third

  async run(factory: FactoryService) {
    await factory.use(CommentFactory).count(50).create();
  }
}

Seeders with the same order value run in the order they appear in the seeders array. Seeders without an order property default to 0.

Registering Seeders

Register seeders in FactoryModule.forRoot():

FactoryModule.forRoot({
  factories: [UserFactory, PostFactory, CommentFactory],
  seeders: [UserSeeder, PostSeeder, CommentSeeder],
});

Running Seeders

Run All Seeders

Call seed() to run all registered seeders in order:

await factoryService.seed();

Run a Single Seeder

Call runSeeder() to run a specific seeder without executing the others:

await factoryService.runSeeder(UserSeeder);

Seed Endpoint

A common pattern is to expose a seed endpoint for development:

import { Controller, Post, HttpCode } from "@nestjs/common";
import { FactoryService } from "@nestbolt/factory";

@Controller("seed")
export class SeedController {
  constructor(private readonly factory: FactoryService) {}

  @Post()
  @HttpCode(200)
  async seed() {
    await this.factory.seed();
    return { message: "Database seeded successfully" };
  }

  @Post("users")
  @HttpCode(200)
  async seedUsers() {
    await this.factory.runSeeder(UserSeeder);
    return { message: "Users seeded" };
  }
}

Using Faker in Seeders

Access the Faker instance via factory.getFaker() for any data generation outside of factories:

export class DatabaseSeeder implements Seeder {
  order = 0;

  async run(factory: FactoryService): Promise<void> {
    const faker = factory.getFaker();

    // Use Faker directly alongside factories
    const users = await factory.use(UserFactory).count(5).createMany();

    for (const user of users) {
      const postCount = faker.number.int({ min: 1, max: 5 });
      await factory.use(PostFactory)
        .count(postCount)
        .override({ userId: user.id })
        .create();
    }
  }
}

Multiple Seeders Example

A typical project might organize seeders like this:

src/
  seeders/
    database.seeder.ts    # order: 0 -- orchestrates everything
    user.seeder.ts        # order: 0 -- base users
    post.seeder.ts        # order: 10 -- posts (depends on users)
    comment.seeder.ts     # order: 20 -- comments (depends on posts)
// database.seeder.ts -- or you can register all seeders directly
export class DatabaseSeeder implements Seeder {
  order = 0;

  async run(factory: FactoryService): Promise<void> {
    // Create base data
    await factory.use(UserFactory).count(10).create();
    await factory.use(UserFactory).state("admin").count(2).create();

    // Create content
    await factory.use(PostFactory).count(20).create();
    await factory.use(CommentFactory).count(50).create();
  }
}