Examples
Self-contained TypeScript examples, each highlighting a storymock feature. Run any example with npx tsx examples/<file>.ts.
Fakers & Composability
Core domains, semantic domains, constraint chaining, composability, batch generation.
Highlights:
numeric(),text(),temporal(),bool(),choice(),collection()- Constraint chaining:
.min(),.max(),.float(),.precision(),.length() - Format methods that change return type:
.hex(),.iso() - Faker-in-faker composability:
temporal().year(numeric().min(2020).max(2025)) - Batch (
.create(5)) and unique (.unique().create(3)) .nullable()and.optional()
typescript
import { numeric, text, person, temporal, choice } from 'storymock';
const id = text().uuid().create(); // '550e8400-e29b-...'
const age = person().age().min(18).max(65).create(); // 34
const price = numeric().min(1).max(999).precision(2).create(); // 42.99
const date = temporal().year(numeric().min(2020).max(2025)).create(); // Date
const roles = choice('viewer', 'editor', 'admin').unique().create(3);Traits & Customization
Named states, combining traits, inline overrides, immutable forking.
Highlights:
- Defining traits with
.trait('name', { ... }) - Applying one trait:
.with('completed') - Combining traits left-to-right:
.with('urgent', 'completed') - Inline overrides:
.with({ title: 'Fix bug #123' }) - Traits + overrides:
.with('urgent', { assignee: 'Alice' }) - Immutable forking: base schema unchanged after
.with()
typescript
import { schema, text, lorem, person, choice, collection } from 'storymock';
const TaskSchema = schema<Task>({
id: text().uuid(),
title: lorem().sentence(),
priority: choice('low', 'medium', 'high'),
assignee: person().fullName(),
}).trait('urgent', { priority: 'high' as const });
TaskSchema.with('urgent').create();
TaskSchema.with('urgent', { assignee: 'Alice' }).create();Conditional Fields
when() for conditional logic, derive() for computed fields, dependency resolution.
Highlights:
when()with string keys:when('type', { percentage: ..., fixed: ... })when()with numeric keys and_defaultwhen()with boolean keysderive()computing from resolved siblingsderive()returning a faker instead of a literal- Field resolution order (DAG)
typescript
import { schema, choice, numeric, derive, when } from 'storymock';
const CouponSchema = schema<Coupon>({
type: choice('percentage', 'fixed'),
value: when('type', {
percentage: numeric().min(5).max(100),
fixed: numeric().min(10).max(500).precision(2),
}),
label: derive(({ type, value }) =>
type === 'percentage' ? `${value}% OFF` : `$${value} OFF`
),
});Story Composition
ref() for foreign keys, .setup() for wiring, addMany, type accumulation.
Highlights:
story().add()and.addMany()with type accumulationref('entry')resolving foreign keys via.id()ref('entry', 'field')referencing a specific fieldref()onaddManyentries resolving to an array of IDs.setup()for complex relationship wiring- Inline overrides with
ref()
typescript
import { story, ref } from 'storymock';
const blogStory = story()
.add('author', AuthorSchema)
.addMany('posts', PostSchema, 3, { authorId: ref('author') })
.add('comment', CommentSchema, { authorId: ref('author') })
.setup((m) => { m.comment.postId = m.posts[0].id; });
const { author, posts, comment } = blogStory.create();
// comment.authorId === author.id ✓Story Inheritance
Base stories, extending, setup accumulation, cascading .with(), targeting.
Highlights:
- Base story → extended story with additional entries
.setup()accumulation across inheritance- Cascading
.with()across multiple entries - Targeting specific
addManyitems:.with('teams[0]', { ... }) - Forking independent variants from the same base
- Reusable wiring functions
typescript
const orgBase = story()
.add('org', OrgSchema)
.addMany('teams', TeamSchema, 2, { orgId: ref('org') });
const orgWithMembers = orgBase
.addMany('members', MemberSchema, 4)
.setup(wireTeamMembers);
// Fork independent variants
const proOrg = orgWithMembers.with('org', { plan: 'pro' as const });
const deletedOrg = orgWithMembers.with('org', 'deleted');Seeding & Determinism
.seed() at every level, configure({ seed }), reproducible snapshots.
Highlights:
- Faker seed:
numeric().seed(42).create() - Schema seed:
UserSchema.seed(42).create() - Story seed:
myStory.seed(42).create() - Seed precedence (faker > schema > story > global)
- Global seed via
configure({ seed: 42 }) - Deterministic test assertions
typescript
import { numeric, schema, configure } from 'storymock';
// Same seed → same value, every time
const a = numeric().min(1).max(100).seed(42).create();
const b = numeric().min(1).max(100).seed(42).create();
// a === b ✓
// Schema-level seed for full objects
const user1 = UserSchema.seed(42).create();
const user2 = UserSchema.seed(42).create();
// user1.id === user2.id ✓Running Examples
bash
git clone https://github.com/storymock/storymock.git
cd storymock
pnpm install
npx tsx examples/file.tsContributing an Example
Examples highlight features, not business scenarios. See the Contributing guide for the full checklist.