NestboltNestbolt

@nestbolt/factory

Factory Builder

The fluent builder API for generating entities -- count, state, override, sequence, callbacks, make, and create.

The FactoryBuilder is the core API for generating entities. You get a builder instance by calling factoryService.use(FactoryClass), then chain methods to configure how entities are generated.

Getting a Builder

import { FactoryService } from "@nestbolt/factory";
import { UserFactory } from "./factories/user.factory";

@Injectable()
export class MyService {
  constructor(private readonly factory: FactoryService) {}

  async generateData() {
    const builder = this.factory.use(UserFactory);
    // chain methods on builder...
  }
}

Builder Methods

count(n)

Set the number of entities to generate. Defaults to 1.

await factoryService.use(UserFactory).count(10).create();

When count is 1, make() and create() return a single entity. When count is greater than 1, they return an array.

state(stateOrOverrides)

Apply a state to the generated entities. Accepts a string (named state method), an object (partial attributes), or a function:

// Named state -- calls the admin() method on the factory
await factoryService.use(UserFactory).state("admin").create();

// Object state -- merges directly
await factoryService.use(UserFactory).state({ role: "moderator" }).create();

// Function state -- receives Faker for dynamic values
await factoryService.use(UserFactory)
  .state((faker) => ({ age: faker.number.int({ min: 18, max: 30 }) }))
  .create();

Multiple states can be chained. They are applied in order, with later states overriding earlier ones:

await factoryService.use(UserFactory)
  .state("admin")
  .state({ age: 30 })
  .create();

override(attrs)

Override specific fields with fixed values. Overrides have the highest priority and are applied after all states and sequences:

await factoryService.use(UserFactory)
  .state("admin")
  .override({ email: "admin@example.com" })
  .create();

Multiple override() calls merge together:

await factoryService.use(UserFactory)
  .override({ email: "test@example.com" })
  .override({ name: "Test User" })
  .create();
// Both email and name are overridden

sequence(field, seq)

Apply a Sequence to a field. The sequence generates a new value for each entity in the batch:

import { Sequence } from "@nestbolt/factory";

await factoryService.use(UserFactory)
  .count(3)
  .sequence("email", Sequence.from(i => `user${i}@test.com`))
  .create();
// user0@test.com, user1@test.com, user2@test.com

See Sequences for all available sequence types.

afterMaking(callback)

Register a callback that runs after each entity is instantiated (but not persisted). The callback receives the entity and the Faker instance:

await factoryService.use(UserFactory)
  .afterMaking(async (user, faker) => {
    user.displayName = user.name.toUpperCase();
  })
  .make();

Multiple callbacks can be registered and execute in order.

afterCreating(callback)

Register a callback that runs after each entity is persisted to the database:

await factoryService.use(UserFactory)
  .afterCreating(async (user, faker) => {
    // Create related entities
    await factoryService.use(PostFactory)
      .override({ userId: user.id })
      .count(3)
      .create();
  })
  .create();

Finalizing Methods

make()

Generate entities without persisting to the database. Returns a single entity when count is 1, or an array when count is greater than 1:

const user = await factoryService.use(UserFactory).make() as User;
const users = await factoryService.use(UserFactory).count(5).make() as User[];

makeMany()

Generate entities without persisting. Always returns an array, even for a single entity:

const users = await factoryService.use(UserFactory).makeMany();
// users is always User[]

create()

Generate entities and persist them to the database. Returns a single entity when count is 1, or an array when count is greater than 1:

const user = await factoryService.use(UserFactory).create() as User;
const users = await factoryService.use(UserFactory).count(5).create() as User[];

Requires a DataSource to be available (TypeORM must be configured). Throws an error if no database connection is available.

createMany()

Generate and persist entities. Always returns an array:

const users = await factoryService.use(UserFactory).count(5).createMany();
// users is always User[]

API Summary

MethodReturnsDescription
count(n)thisSet number of entities to generate
state(name | object | fn)thisApply a state
override(attrs)thisOverride specific fields (highest priority)
sequence(field, seq)thisApply a sequence to a field
afterMaking(fn)thisCallback after instantiation
afterCreating(fn)thisCallback after persistence
make()T | T[]Instantiate without persisting
makeMany()T[]Instantiate and always return array
create()T | T[]Persist and return
createMany()T[]Persist and always return array

Override Priority

When multiple sources set the same field, the following priority applies (highest wins):

  1. override() -- highest priority
  2. sequence() -- overrides states and definition
  3. state() -- overrides definition (later states override earlier ones)
  4. definition() -- base values (lowest priority)