
fabricator
Fabricate typed data from composable schemas.
Define a shape once, get fully typed, randomized, probabilistic test data, perfectly reproducible from seed parameters.
import { } from "@ghostry/fabricator";
const { , } = ({
: new (), // default source of entropy
: "1234", // optional additional entropy
});
const = .({
: ..({ : { : 1, : 25 } }),
: ..({ : 1, : 500 }),
: .,
: ..,
: .(..({ : { : 15 } })).({
: { : 5 },
}),
});
const = new ();
const = .();
const createdAt = .;
// Everything random except what you pin:
const = .({ : "Widget", : true });The value type falls out of the schema — no generics to write, no as casts, no drift between a fixture and the type it stands in for.
Every value is drawn from a stream keyed by seed, clock, file, and structural path. .trace describes exactly where a value came from and facilitates replay.
Data streams are keyed by structural position, so adding, removing, or reordering a field changes only that field's data.
.extend(), .refine(), and .override() build schemas out of schemas. Per-call overrides pin what a test cares about and leave the rest random.
Object key missing, key present as undefined, and value null are different facts. The omittable, optional, nullable, nullish, and undefinable primitives allow describing them precisely.
T.opaque and .as() cover anything with no primitive; registry.extend() brings your own builders; the TypeBox adapter turns a schema into a validator.