@nestbolt/factory
Sequences
Auto-increment, cycle, and compute field values across multiple generated entities.
Sequences generate unique or predictable values for fields across multiple entities in a batch. They are especially useful for fields that need to be unique (like email addresses) or follow a pattern (like incrementing IDs).
Importing
import { Sequence } from "@nestbolt/factory";Built-in Sequence Types
Sequence.from(callback)
The most flexible sequence type. Pass a callback that receives an auto-incrementing index (starting from 0):
await factoryService.use(UserFactory)
.count(3)
.sequence("email", Sequence.from(i => `user${i}@test.com`))
.create();
// user0@test.com, user1@test.com, user2@test.comSequence.increment(start?)
Generates incrementing numbers. Starts from 1 by default:
await factoryService.use(UserFactory)
.count(3)
.sequence("employeeId", Sequence.increment())
.create();
// 1, 2, 3
await factoryService.use(UserFactory)
.count(3)
.sequence("employeeId", Sequence.increment(100))
.create();
// 100, 101, 102Sequence.cycle(values)
Cycles through an array of values, wrapping around when the end is reached:
await factoryService.use(PostFactory)
.count(6)
.sequence("status", Sequence.cycle(["draft", "published", "archived"]))
.create();
// draft, published, archived, draft, published, archivedCustom Sequences
Create a Sequence directly with any callback function:
const seq = new Sequence((i) => i * 10);
seq.next(); // 0
seq.next(); // 10
seq.next(); // 20Resetting Sequences
Call reset() to restart a sequence from index 0:
const seq = Sequence.increment();
seq.next(); // 1
seq.next(); // 2
seq.next(); // 3
seq.reset();
seq.next(); // 1Note that sequences created inline in the builder (e.g., .sequence("email", Sequence.from(...))) are fresh for each builder chain. You only need reset() when reusing a sequence instance across multiple operations.
Combining with Other Builder Methods
Sequences are applied after states but before overrides. This means:
- States do not override sequence values
override()does override sequence values
// Sequence wins over the state's email
await factoryService.use(UserFactory)
.state({ email: "ignored@test.com" })
.sequence("email", Sequence.from(i => `user${i}@test.com`))
.create();
// email: "user0@test.com"
// Override wins over the sequence
await factoryService.use(UserFactory)
.sequence("email", Sequence.from(i => `user${i}@test.com`))
.override({ email: "forced@test.com" })
.create();
// email: "forced@test.com"Practical Examples
Unique Usernames
await factoryService.use(UserFactory)
.count(5)
.sequence("username", Sequence.from(i => `testuser_${i}`))
.create();Ordered Positions
await factoryService.use(TaskFactory)
.count(10)
.sequence("position", Sequence.increment())
.create();Rotating Categories
await factoryService.use(ProductFactory)
.count(12)
.sequence("category", Sequence.cycle(["electronics", "clothing", "books", "food"]))
.create();Computed Slugs
await factoryService.use(PostFactory)
.count(3)
.sequence("slug", Sequence.from(i => `post-${i + 1}`))
.create();
// post-1, post-2, post-3