Introducing Socket Firewall: Free, Proactive Protection for Your Software Supply Chain.Learn More
Socket
Book a DemoInstallSign in
Socket

@aklinker1/zero-factory

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aklinker1/zero-factory

Zero dependency object factory generator for testing

latest
Source
npmnpm
Version
1.1.4
Version published
Maintainers
1
Created
Source

@aklinker1/zero-factory

JSR NPM Version Docs API Reference License

Zero dependency object factory generator for testing.

import { createFactory, createSequence } from "@aklinker1/zero-factory";

const userFactory = createFactory<User>({
  id: createSequence("user-"),
  username: "example-username",
  email: () => "example-email-" + Math.random(),
});

userFactory({ id: "test", username: "user" });
// => {
//   id: "test",
//   username: "user",
//   email: "example-email-0.20088082049103195"
// }
npm i @aklinker1/zero-factory

Features:

  • ✅ Type-safe
  • ✨ Deeply merge overrides with default values
  • 🔢 Sequence generator for IDs
  • 🎨 "traits" - define multiple variants of default values
  • ⚡ Compatible with all fake data generators (@ngneat/falso, faker-js, chance, casual, etc)

Not Supported:

  • Class instances: Only objects can be created. Factories will not create class instances.

Usage

Factories

Use createFactory to build an object factory. Object factories are simple functions that return an object:

const userFactory = createFactory<User>({
  id: "user-id",
  username: "username",
  email: "example@gmail.com",
  preferences: {
    receiveMarketingEmails: true,
    receiveSecurityEmails: true,
  },
});
// typeof userFactory = (overrides?: DeepPartial<User>) => User

Then, to get an object conforming to the User type, just call the factory as a function:

const user = userFactory();
// => {
//   id: "user-id",
//   username: "username",
//   email: "example@gmail.com",
//   preferences: {
//     receiveMarketingEmails: true,
//     receiveSecurityEmails: true,
//   }
// }

You can also override specific properties at any level:

const user = userFactory({
  username: "overridden",
  preferences: {
    receiveMarketingEmails: false,
  },
});
// => {
//   id: "user-id",
//   username: "overridden",
//   email: "example@gmail.com",
//   preferences: {
//     receiveMarketingEmails: false,
//     receiveSecurityEmails: true,
//   }
// }

[!IMPORTANT] Arrays are not deeply merged. If a property is an array, overrides will fully replace it, like any other value.

Function Defaults

In addition to static values, the factory definition accepts functions for properties:

const userFactory = createFactory({
  email: () => `example.${Math.floor(Math.random() * 1000)}@gmail.com`,
  // ...
});

Every time the factory is called, this will call the function and, in this case, generate a different email each time:

userFactory(); // { email: "example.424@gmail.com", ... }
userFactory(); // { email: "example.133@gmail.com", ... }

This is where fake data generators and sequences come in clutch:

import { createFactory, createSequence } from "@aklinker1/zero-factory";
import {
  randEmail, // () => string
  randUsername, // () => string
  randBoolean, // () => boolean
} from "@ngneat/falso";

const userFactory = createFactory({
  id: createSequence("user-"),
  username: randUsername,
  email: randEmail,
  preferences: {
    receiveMarketingEmails: randBoolean,
    receiveSecurityEmails: randBoolean,
  },
});

Many

You can generate multiple objects using factory.many(...). This method will return an array of objects.

userFactory.many(2, { username: "override" });
// [
//   { usenrame: "override", ... }
//   { usenrame: "override", ... }
// ]

Overridden fields apply to all the returned objects.

Traits

If there are common variants or "traits" of an object you want to be able to generate, use factory.trait(...):

const userFactory = createFactory({
  // same as above
}).trait("noEmails", {
  preferences: {
    receiveMarketingEmails: false,
    receiveSecurityEmails: false,
  },
});

Then, to generate an object using this trait, the trait is a function defined on the object factory:

const user = userFactory.noEmails();
// => {
//   id: "user-id",
//   username: "username",
//   email: "example@gmail.com",
//   preferences: {
//     receiveMarketingEmails: false,
//     receiveSecurityEmails: false,
//   }
// }

When using a trait and overriding specific properties, the trait's default values are applied before the overrides:

const user = userFactory.noEmails({ username: "overridden" });
// => {
//   id: "user-id",
//   username: "overridden",
//   email: "example@gmail.com",
//   preferences: {
//     receiveMarketingEmails: false,
//     receiveSecurityEmails: false,
//   }
// }

Associations

If you want to override one or more fields based on a single value, use associations:

const postFactory = createFactory<Post>({
  id: createSequence(),
  userId: userIdSequence,
  // ...
}).associate("user", (user: User) => ({ userId: user.id }));

Then to generate a post associated with a user, use with:

user;
// => {
//   id: 3,
//   ...
// }

postFactory.with({ user })();
// => {
//   id: 0,
//   userId: 3,
//   ...
// }

Note that with returns a factory function, which needs to be called to generate the final object. This allows you to chain other utilities like .many and/or traits:

postFactory.with({ user }).noEmails.many(3);

Sequences

For values like IDs, it can be useful to generate them incrementally instead of using randomized values. Use the createSequence function to do this:

const userIdSequence = createSequence((i) => `user-${i}`);

userIdSequence(); // "user-0"
userIdSequence(); // "user-1"
userIdSequence(); // "user-2"
// ...

The argument i is a number starting at 0 that gets incremented by 1 each time the sequence is called. The return value can be anything (string, boolean, object, integer, etc).

const intSequence = createSequence((i) => i + 1);
intSequence(); // 1
intSequence(); // 2
intSequence(); // 3
// ...

const boolSequence = createSequence((i) => i % 2 === 0);
boolSequence(); // true
boolSequence(); // false
boolSequence(); // true
// ...

However, the most common types of return values are integers and strings. For both, there is a shorthand:

const intSequence = createSequence();
intSequence(); // 0
intSequence(); // 1
intSequence(); // 2
// ...

const strSequence = createSequence("prefix-");
intSequence(); // "prefix-0"
intSequence(); // "prefix-1"
intSequence(); // "prefix-2"

Keywords

factory

FAQs

Package last updated on 11 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts