GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - Goldziher/interface-forge: Graceful mock-data generation using TypeScript

BranchesTags
Open more actions menu

Latest commit

 

History

423 Commits
423 Commits

Folders and files

NameName
Last commit message
Last commit date
.ai-rulez
.ai-rulez
 
 
.github
.github
 
 
assets
assets
 
 
docs
docs
 
 
examples
examples
 
 
mise-tasks
mise-tasks
 
 
src
src
 
 
.gitignore
.gitignore
 
 
.oxfmtrc.json
.oxfmtrc.json
 
 
.oxlintrc.json
.oxlintrc.json
 
 
CHANGELOG.md
CHANGELOG.md
 
 
CONTRIBUTING.md
CONTRIBUTING.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
SECURITY.md
SECURITY.md
 
 
mise.lock
mise.lock
 
 
mise.toml
mise.toml
 
 
package.json
package.json
 
 
pnpm-lock.yaml
pnpm-lock.yaml
 
 
pnpm-workspace.yaml
pnpm-workspace.yaml
 
 
poly-hooks.lock
poly-hooks.lock
 
 
poly.lock
poly.lock
 
 
poly.toml
poly.toml
 
 
toolchains.toml
toolchains.toml
 
 
tsconfig.json
tsconfig.json
 
 
vite.config.ts
vite.config.ts
 
 

Repository files navigation

Interface-Forge Logo

Interface-Forge

npm version License: MIT TypeScript Downloads

A TypeScript library for creating strongly typed mock data factories. Built on Faker.js with advanced composition patterns, database persistence, fixture caching, and optional Zod and JSON Schema integration.

Support This Project

If you find interface-forge helpful, please consider sponsoring the development:

Sponsor on GitHub

Your support helps maintain and improve this library for the community! 🚀

Features

  • 🔒 Type-Safe: Full TypeScript support with compile-time validation
  • 🚀 Zero Learning Curve: Extends Faker.js - all Faker methods work out of the box
  • 🔄 Advanced Composition: Build complex object relationships with compose() and extend()
  • 🗄️ Database Integration: Built-in persistence with Mongoose, Prisma, TypeORM adapters
  • 📁 Fixture Caching: Cache generated data for consistent test scenarios
  • 📐 Schema Integration: Generate data directly from Zod or JSON Schema with validation
  • 🔗 Hooks & Transforms: Pre/post-build data transformation and validation
  • 🎲 Deterministic: Seed generators for reproducible test data

📚 Complete Documentation | 📂 Examples

Installation

# npm
pnpm add --save-dev interface-forge

# yarn
yarn add --dev interface-forge

# pnpm
pnpm add --save-dev interface-forge

# For Zod integration (optional)
pnpm add zod

# For JSON Schema integration (optional)
pnpm add ajv ajv-formats

# For GraphQL integration (optional)
pnpm add graphql

Quick Start

Basic Factory

import { Factory } from 'interface-forge';

interface User {
    id: string;
    name: string;
    email: string;
    age: number;
}

const userFactory = new Factory<User>((faker) => ({
    id: faker.string.uuid(),
    name: faker.person.fullName(),
    email: faker.internet.email(),
    age: faker.number.int({ min: 18, max: 65 }),
}));

// Generate single object
const user = userFactory.build();

// Generate multiple objects
const users = userFactory.batch(5);

// Override properties
const admin = userFactory.build({ name: 'Admin User' });

Zod Integration

import { z } from 'zod/v4';
import { ZodFactory } from 'interface-forge/zod';

const userSchema = z.object({
    id: z.string().uuid(),
    name: z.string().min(2),
    email: z.string().email(),
    age: z.number().min(18).max(65),
});

const userFactory = new ZodFactory(userSchema);
const user = userFactory.build(); // Automatically validates against schema

JSON Schema Integration

import { JsonSchemaFactory } from 'interface-forge/json-schema';

const userSchema = {
    type: 'object',
    required: ['id', 'email'],
    properties: {
        id: { type: 'string', format: 'uuid' },
        email: { type: 'string', format: 'email' },
    },
} as const;

const userFactory = new JsonSchemaFactory(userSchema);
const user = userFactory.build(); // Automatically validates with AJV

GraphQL Integration

import { createGraphQLFactories } from 'interface-forge/graphql';

const sdl = `
    type User { id: ID!, name: String!, roles: [Role!]! }
    type Post { author: User!, title: String }
    enum Role { ADMIN USER }
    scalar DateTime
`;

const factories = createGraphQLFactories(sdl, {
    customScalarGenerators: { DateTime: () => '2026-01-01T00:00:00Z' },
});

const post = factories.Post?.build();

Database Persistence

import { MongooseAdapter } from './adapters/mongoose';

const userFactory = new Factory<User>(factoryFn).withAdapter(
    new MongooseAdapter(UserModel),
);

// Create and save to database
const user = await userFactory.create();
const users = await userFactory.createMany(10);

Advanced Composition

const enhancedUserFactory = userFactory.compose<EnhancedUser>({
    profile: profileFactory, // Use another factory
    posts: postFactory.batch(3), // Generate related data
    isActive: true, // Static values
});

Core Features

Factory Methods

  • build() / buildAsync() - Generate single objects
  • batch() / batchAsync() - Generate multiple objects
  • extend() - Create factory variations
  • compose() - Combine multiple factories
  • create() / createMany() - Database persistence

Hooks & Validation

  • beforeBuild() - Transform data before generation
  • afterBuild() - Transform data after generation
  • Full async support for external API calls

Lazy Evaluation

  • factory.use(fn, ...args) - Defer a function call until the object is built
  • Async lazy values work with buildAsync() and batchAsync():
const UserFactory = new Factory<User>((factory) => ({
    id: factory.string.uuid(),
    token: factory.use(async () => await generateToken()),
}));

const user = await UserFactory.buildAsync();
  • Sync lazy values work with build(); if an async lazy value reaches build() or batch(), a clear ConfigurationError tells you to use buildAsync().

Presets

  • factory.preset(name, values) - Register named partial overrides on a factory
  • Apply one or more presets via { presets: ['first', 'second'] } in build()/batch(); later presets override earlier ones and explicit kwargs override all presets:
const userFactory = new Factory<User>((faker) => ({
    name: faker.person.fullName(),
    role: 'user',
})).preset('admin', { role: 'admin' });

const admin = userFactory.build(undefined, { presets: ['admin'] });

Constraint Helpers

  • factory.constraints.min / .max / .between - Constrain generated numbers (clamped)
  • factory.constraints.pattern - Regenerate until a string matches a regex
  • factory.constraints.custom - Regenerate until a predicate accepts the value
  • factory.constraints.unique - Factory-local uniqueness across builds and batch items, tracked per field
  • Retry-based helpers throw a ConstraintError (with field, constraint, attempts) once the attempt limit is reached:
const orderFactory = new Factory<Order>((faker) => ({
    id: factory.constraints.unique('id', () => faker.string.uuid()),
    total: factory.constraints.between(1, 500, () => faker.number.float({ min: 0, max: 1000 })),
}));

Type Utilities

  • FactoryOutput<F> - Extract the output type of any factory
  • extend() has two overloads: a full-override factory function (returning the complete extended type) or an added-fields factory function returning only the new fields, which yields Factory<T & Added>; the base fields are preserved automatically.
import { expectTypeOf } from 'expect-type';
import type { FactoryOutput } from 'interface-forge';

const adminFactory = userFactory.extend((factory) => ({
    permissions: ['read', 'write'],
}));

type Admin = User & { permissions: string[] };
expectTypeOf<FactoryOutput<typeof adminFactory>>().toEqualTypeOf<Admin>();

Fixture Caching

  • Cache generated data for consistent tests
  • Signature validation for factory changes
  • Node.js only (browser fallback available)

Utility Generators

  • CycleGenerator - Predictable value cycling
  • SampleGenerator - Random sampling without repeats
  • factory.sequence.increment() - Incrementing numeric sequences
  • factory.sequence.template() - Template-based string sequences
  • factory.sequence.date() - Date/time sequences

Documentation

📚 Complete Documentation

  • Getting Started
  • Core Concepts
  • Zod Integration
  • JSON Schema Integration
  • Advanced Features
  • API Reference

Examples

All examples are available in the ./examples directory:

Feature Example
Basic Usage 01-basic-usage.ts
Factory Composition 02-advanced-composition.ts
Testing Integration 03-testing-examples.ts
Zod Schemas 07-zod-basic.ts
Database Persistence adapters/

Contributing

We welcome contributions! Please read our contributing guidelines.

License

MIT License - see LICENSE for details.

About

Graceful mock-data generation using TypeScript

goldziher.github.io/interface-forge/

Topics

factoriesfakerfakerjstestingteststypescript

Resources

Readme
MIT license

Contributing

Contributing

Security policy

Security policy
Activity

Stars

104 stars

Watchers

1 watching

Forks

9 forks
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.