Quick start
import { initialize } from "@ghostry/fabricator";
const { T, Fabricator } = initialize({ seed: "1234" });
const ProductSchema = T.object({
name: T.string.whereby({ length: { min: 1, max: 25 } }),
price: T.number.whereby({ min: 1, max: 500 }),
inStock: T.boolean,
createdAt: T.date.past,
tags: T.array(T.string.whereby({ length: { max: 15 } })).whereby({
length: { max: 5 },
}),
});
const Product = new Fabricator(ProductSchema);
const item = Product.fabricate();
// { name: "...", price: ..., inStock: ..., createdAt: ..., tags: [...] }That's the whole loop:
initialize(...)gives youT(a namespace of type builders) andFabricator(a constructor for turning a Schema into something live).T.object({ ... })builds a Schema — inert, serializable data describing a shape. Building it draws no randomness.new Fabricator(schema)builds a live Fabricator with a.fabricate()method..fabricate()is the only place randomness actually happens.
See Mental model for why this three-layer split exists, and Reproducibility for what seed: '1234' buys you.
Overriding specific fields
Fabricate with everything random except a few fields you care about:
const item = Product.fabricate({ name: "Widget", inStock: true });This uses the Fabricator's own already-drawn randomness for every other field — it's a per-call override, not a new schema. See Composition for the schema-level equivalent, .override(...).
