@nestbolt/factory
Quick Start
Get up and running with @nestbolt/factory in five minutes -- define a factory, register the module, and generate test data.
This guide walks through a complete working example: defining a factory, registering the module, creating a seeder, and generating data.
1. Define Your Entity
A standard TypeORM entity -- nothing special is required:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity("users")
export class User {
@PrimaryGeneratedColumn("uuid")
id!: string;
@Column()
name!: string;
@Column()
email!: string;
@Column({ default: "user" })
role!: string;
}2. Define a Factory
Extend BaseFactory<T> and implement the entity getter and definition() method. The definition() method receives a Faker instance and returns default attributes:
import { BaseFactory } from "@nestbolt/factory";
import type { Faker } from "@faker-js/faker";
import { User } from "./entities/user.entity";
export class UserFactory extends BaseFactory<User> {
get entity() {
return User;
}
definition(faker: Faker): Partial<User> {
return {
name: faker.person.fullName(),
email: faker.internet.email(),
role: "user",
};
}
admin(): Partial<User> {
return { role: "admin" };
}
}3. Register the Module
Import FactoryModule in your root AppModule and call forRoot() with your factory classes. The module registers globally, so you only need to import it once.
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { FactoryModule } from "@nestbolt/factory";
import { User } from "./entities/user.entity";
import { UserFactory } from "./factories/user.factory";
@Module({
imports: [
TypeOrmModule.forRoot({
type: "postgres",
host: "localhost",
port: 5432,
database: "myapp",
entities: [User],
synchronize: true, // development only
}),
FactoryModule.forRoot({
factories: [UserFactory],
}),
],
})
export class AppModule {}4. Use in Your Code
Inject FactoryService and use the fluent builder API:
import { Injectable } from "@nestjs/common";
import { FactoryService } from "@nestbolt/factory";
import { UserFactory } from "./factories/user.factory";
@Injectable()
export class SeedService {
constructor(private readonly factory: FactoryService) {}
async seed() {
// Create 10 regular users
await this.factory.use(UserFactory).count(10).create();
// Create 2 admin users
await this.factory.use(UserFactory).state("admin").count(2).create();
// Make an entity without persisting
const user = await this.factory.use(UserFactory).make();
}
}5. Define a Seeder (Optional)
Seeders let you organize your data generation into reusable, ordered classes:
import type { Seeder, FactoryService } from "@nestbolt/factory";
import { UserFactory } from "./factories/user.factory";
export class DatabaseSeeder implements Seeder {
order = 0; // lower runs first
async run(factory: FactoryService): Promise<void> {
await factory.use(UserFactory).count(10).create();
await factory.use(UserFactory).state("admin").count(2).create();
}
}Register the seeder and run it:
// In module configuration
FactoryModule.forRoot({
factories: [UserFactory],
seeders: [DatabaseSeeder],
});
// In your service
await factoryService.seed(); // runs all seeders sorted by order6. Test It
Create a simple controller to trigger seeding:
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" };
}
}Then trigger it:
curl -X POST http://localhost:3000/seed{ "message": "Database seeded successfully" }What Happened Behind the Scenes
FactoryModule.forRoot()registered your factory classes and madeFactoryServiceavailable globally.factoryService.use(UserFactory)looked up the registeredUserFactoryand returned aFactoryBuilder<User>..count(10)configured the builder to generate 10 entities..state("admin")applied theadmin()state method, overriding therolefield..create()calleddefinition()for each entity, applied states and overrides, instantiatedUserobjects, and persisted them via TypeORM'sRepository.save().
Next Steps
- Configuration -- all module options including async configuration and Faker seeds.
- Defining Factories -- lifecycle hooks, state methods, and best practices.
- Factory Builder -- full builder API with
make,create,override,sequence, and callbacks. - Seeders -- organize data generation with ordered, composable seeder classes.