@jaypie/fabricator
v0.3.2
Published
Seeded, deterministic test data generation built on @faker-js/faker
Readme
@jaypie/fabricator
Seeded, deterministic test data generation built on @faker-js/faker
Installation
npm install --save-dev @jaypie/fabricatorUsage
Basic Usage
import { fabricator } from "@jaypie/fabricator";
// Create a fabricator instance
const fab = fabricator();
// Access faker.js API directly
const email = fab.internet.email();
const firstName = fab.person.firstName();
const address = fab.location.streetAddress();Seeded Generation
For deterministic, reproducible test data:
import { fabricator } from "@jaypie/fabricator";
// Create seeded fabricator
const fab = fabricator("my-seed");
// Will always generate the same data with the same seed
const email = fab.internet.email(); // Always the same emailRandom Numbers
Generate random numbers with various options:
import { fabricator } from "@jaypie/fabricator";
const fab = fabricator("seed");
// Basic random float between 0 and 1
const basic = fab.random();
// Integer between min and max
const integer = fab.random({ min: 1, max: 10, integer: true });
// Normal distribution
const normal = fab.random({ mean: 50, stddev: 10 });
// Currency (2 decimal places)
const price = fab.random({ min: 10, max: 100, currency: true });
// Custom precision
const precise = fab.random({ min: 0, max: 1, precision: 4 });You can also use the standalone random function:
import { random } from "@jaypie/fabricator";
const rng = random("seed");
const value = rng({ min: 1, max: 100 });Word Combinations
Generate random word combinations:
const fab = fabricator();
// Returns one of three patterns:
// - adjective + noun (e.g., "happy dog")
// - adjective + verb (e.g., "quick run")
// - noun + verb (e.g., "cat jump")
const words = fab.words();Corpus
Generate deterministic corpus text for fixtures, benchmarks, or seeded prose:
const fab = fabricator("my-seed");
fab.corpus(); // 108 words of English-ish prose
fab.corpus(1000); // 1000 words
fab.corpus({ wordsPerPeriod: 10 });
fab.corpus(500, { typoRate: 0.20 });Each call advances the fabricator's state, so successive calls with the same parameters return different output. Re-running from a fresh fabricator("my-seed") reproduces the same sequence:
const f1 = fabricator("seed");
const a = f1.corpus(100);
const b = f1.corpus(100);
// a !== b
const f2 = fabricator("seed");
f2.corpus(100) === a; // true
f2.corpus(100) === b; // trueDifferent parameters produce independent streams, not truncated variants — fabricator("seed").corpus(100) and fabricator("seed").corpus(101) differ across the whole text, not by one word.
Custom corpus
Pass corpus (raw text) or words (explicit weights) to mix domain vocabulary into the output. By default the custom pool is blended 50/50 with the default English pool; typo rate (~6%) and phonotactic invention rate (~3%) stay at their defaults:
fab.corpus(500, { corpus: deployLogText });
fab.corpus(500, { words: [["deploy", 5], ["pipeline", 3], ["lambda", 2]] });
// Tune the mix
fab.corpus(500, { corpus: deployLogText, blend: 0.7 });
// Pure custom — drop default English entirely
fab.corpus(500, { corpus: deployLogText, replaceDefaults: true });Custom token functions
For tokens that aren't word-shaped — UUIDs, dollar amounts, IDs — pass functions. Each function receives the fabricator and emits one token per draw. The weight is the share of total content tokens taken from the main word stream:
// Single function — shorthand
fab.corpus(500, {
functions: [({ fab }) => fab.string.uuid(), 0.03],
});
// Multiple functions
fab.corpus(500, {
functions: [
[({ fab }) => fab.string.uuid(), 0.03],
[({ fab }) => "$" + fab.finance.amount(), 0.04],
[({ fab }) => fab.internet.email(), 0.02],
],
});Output is still deterministic — function calls advance the fabricator's state in a consistent order across replays.
Full options
interface CorpusOptions {
corpus?: string; // raw text → derive weights
words?: ReadonlyArray<readonly [string, number]>; // explicit weights
blend?: number; // share given to custom pool, default 0.5
replaceDefaults?: boolean; // skip default English entirely
typos?: ReadonlyArray<readonly [string, number]>; // override typo pool
phonotactic?: PhonotacticOptions; // tune invented words
typoRate?: number; // default 0.06
phonotacticRate?: number; // default 0.03
wordsPerPeriod?: number; // default 17
wordsPerComma?: number; // default 22
periodsPerBreak?: number; // default 5
sentences?: boolean; // default true
chars?: number; // generate by char length instead of word count
functions?: // custom token functions
| readonly [CorpusTokenFunction, number]
| ReadonlyArray<readonly [CorpusTokenFunction, number]>;
}
type CorpusTokenFunction = (params: { fab: Fabricator }) => string;Generate Complex Data
Person
Generate realistic person data with probabilistic variations:
const fab = fabricator("seed");
const person = fab.generate.person();
// {
// id: "uuid-v4",
// firstName: "John",
// middleName: "Paul", // may be undefined, lastName, or two names
// lastName: "Smith", // may be hyphenated
// fullName: "John Smith" // may include middle name
// }
// Use a specific ID for deterministic sub-seeding
const seededPerson = fab.generate.person("550e8400-e29b-41d4-a716-446655440000");Person generation uses these probability rules:
- firstName: 2.1% chance to be a lastName instead
- middleName:
- 14.6% chance to be missing
- 2.1% chance to be a lastName
- 0.307% chance to have two middle names
- lastName: 2.1% chance to be hyphenated (two lastNames)
- fullName: 14.6% chance to include middle name
Constants
Probability constants for custom generation:
import { CHANCE } from "@jaypie/fabricator/constants";
const fab = fabricator();
if (fab.number.float() < CHANCE.RARE) {
// 2.1% chance
}
// Available constants:
// CHANCE.UNCOMMON: 0.146 (14.6%)
// CHANCE.RARE: 0.021 (2.1%)
// CHANCE.EPIC: 0.00307 (0.307%)
// CHANCE.LEGENDARY: 0.000441 (0.0441%)API
fabricator(seed?: string | number): Fabricator
Creates a new Fabricator instance with optional seeding.
Fabricator Class
The Fabricator class wraps faker.js and provides additional functionality:
faker: Direct access to the faker.js instancerandom(options?): Generate random numbers with extensive optionswords(): Generate random word combinationscorpus(words?, options?): Generate deterministic corpus text — see Corpus section abovegenerate.person(id?): Generate person data with realistic variations- All faker.js modules: Direct access to
airline,animal,color,commerce,company,database,datatype,date,finance,git,hacker,helpers,image,internet,location,lorem,music,number,person,phone,science,string,system,vehicle,word
Random Options
interface RandomOptions {
min?: number; // Minimum value
max?: number; // Maximum value (defaults to min*2 if only min provided)
mean?: number; // Mean for normal distribution (requires stddev)
stddev?: number; // Standard deviation for normal distribution (requires mean)
integer?: boolean; // Return integer instead of float
start?: number; // Starting offset to add to result
seed?: string; // Override seed for this call
precision?: number; // Number of decimal places
currency?: boolean; // Format as currency (2 decimal places)
}Exports
Main Export
import { fabricator } from "@jaypie/fabricator";Named Exports
import {
Fabricator,
random,
DEFAULT_MIN,
DEFAULT_MAX,
} from "@jaypie/fabricator";
import type {
RandomOptions,
RandomFunction
} from "@jaypie/fabricator";Constants Export
import { CHANCE } from "@jaypie/fabricator/constants";License
MIT
