npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@raicamposs/toolkit

v1.1.0

Published

Um pacote npm com TypeScript.

Downloads

68

Readme

@raicamposs/toolkit

🛠️ A comprehensive TypeScript utility library with type-safe helpers for modern development

npm version License: MIT TypeScript

📦 Installation

npm install @raicamposs/toolkit

🎯 Features

  • 100% TypeScript - Full type safety and IntelliSense support
  • 🎨 Clean Architecture - Organized by responsibility and purpose
  • 🧪 Fully Tested - Comprehensive test coverage with Vitest
  • 📦 Tree-shakeable - Import only what you need
  • 🚀 Zero Dependencies - Lightweight and fast
  • 📚 Well Documented - Clear examples and API documentation

📖 Table of Contents


⏱️ Async Utilities

Utilities for asynchronous operations and timing control.

sleep(ms: number): Promise<void>

Pauses execution for a specified duration.

import { sleep } from '@raicamposs/toolkit';

await sleep(1000); // Wait 1 second
console.log('1 second later');

retryWithBackoff<T>(options): Promise<T>

Retries a function with exponential backoff on failure.

import { retryWithBackoff } from '@raicamposs/toolkit';

const result = await retryWithBackoff({
  fn: async () => fetchData(),
  maxRetries: 3,
  delay: 1000, // Initial delay in ms
});

Parameters:

  • fn: () => Promise<T> - Async function to retry
  • maxRetries: number - Maximum number of retry attempts
  • delay: number - Initial delay between retries (doubles each retry)

🔧 Functional Utilities

Functional programming patterns and helpers.

Either<L, R>

Type-safe error handling without exceptions.

import { Either, Left, Right } from '@raicamposs/toolkit';

function divide(a: number, b: number): Either<string, number> {
  if (b === 0) {
    return new Left('Division by zero');
  }
  return new Right(a / b);
}

const result = divide(10, 2);
if (result.isRight()) {
  console.log(result.value); // 5
} else {
  console.error(result.value); // Error message
}

mapOr<I, O>(value, mapper, defaultValue): O | null

Maps a value through a function, returning a default if null/undefined.

import { mapOr } from '@raicamposs/toolkit';

const user = { name: 'John' };
const upperName = mapOr(user.name, (n) => n.toUpperCase(), 'UNKNOWN');
// Result: 'JOHN'

const noName = mapOr(null, (n) => n.toUpperCase(), 'UNKNOWN');
// Result: 'UNKNOWN'

mapAllOr<I, O>(array, mapper, defaultValue): O[]

Maps all items in an array, returning default if array is null/undefined.

import { mapAllOr } from '@raicamposs/toolkit';

const numbers = [1, 2, 3];
const doubled = mapAllOr(numbers, (n) => n * 2, []);
// Result: [2, 4, 6]

SpecOf<T>

Predicate function type for composable specifications.

import { SpecOf } from '@raicamposs/toolkit';

interface User {
  age: number;
  isPremium: boolean;
}

const isAdult: SpecOf<User> = (user) => user.age >= 18;
const isPremium: SpecOf<User> = (user) => user.isPremium;

and<T>(...specs): SpecOf<T>

Combines multiple specs with AND logic - returns true only if all specs are satisfied.

import { and, SpecOf } from '@raicamposs/toolkit';

const isAdult: SpecOf<User> = (user) => user.age >= 18;
const isPremium: SpecOf<User> = (user) => user.isPremium;

const isAdultPremium = and(isAdult, isPremium);

isAdultPremium({ age: 25, isPremium: true }); // true
isAdultPremium({ age: 25, isPremium: false }); // false
isAdultPremium({ age: 16, isPremium: true }); // false

or<T>(...specs): SpecOf<T>

Combines multiple specs with OR logic - returns true if at least one spec is satisfied.

import { or, SpecOf } from '@raicamposs/toolkit';

const isAdult: SpecOf<User> = (user) => user.age >= 18;
const isPremium: SpecOf<User> = (user) => user.isPremium;

const canAccess = or(isAdult, isPremium);

canAccess({ age: 16, isPremium: true }); // true
canAccess({ age: 25, isPremium: false }); // true
canAccess({ age: 16, isPremium: false }); // false

not<T>(spec): SpecOf<T>

Negates a specification.

import { not, SpecOf } from '@raicamposs/toolkit';

const isAdult: SpecOf<User> = (user) => user.age >= 18;
const isMinor = not(isAdult);

isMinor({ age: 16 }); // true
isMinor({ age: 25 }); // false

Complex Composition Example:

import { and, or, not, SpecOf } from '@raicamposs/toolkit';

interface User {
  age: number;
  isPremium: boolean;
  isActive: boolean;
}

const isAdult: SpecOf<User> = (user) => user.age >= 18;
const isPremium: SpecOf<User> = (user) => user.isPremium;
const isActive: SpecOf<User> = (user) => user.isActive;

// Complex rule: (isAdult AND isPremium) OR (NOT isActive)
const complexRule = or(and(isAdult, isPremium), not(isActive));

const users = [
  { age: 25, isPremium: true, isActive: true }, // true (adult + premium)
  { age: 16, isPremium: false, isActive: false }, // true (not active)
  { age: 25, isPremium: false, isActive: true }, // false
];

const filtered = users.filter(complexRule);

isFlagged<T>(key): SpecOf<T>

Creates a predicate that checks if a boolean property is true.

import { isFlagged } from '@raicamposs/toolkit';

interface User {
  isActive: boolean;
  isPremium: boolean;
}

const isActiveUser = isFlagged<User>('isActive');
const isPremiumUser = isFlagged<User>('isPremium');

const users = [
  { isActive: true, isPremium: false },
  { isActive: false, isPremium: true },
  { isActive: true, isPremium: true },
];

const activeUsers = users.filter(isActiveUser);
// Result: [{ isActive: true, isPremium: false }, { isActive: true, isPremium: true }]

recent<T, K>(config): SpecOf<T>

Creates a specification that checks if a date property is within a specified time window.

import { recent } from '@raicamposs/toolkit';

interface User {
  id: number;
  name: string;
  createdAt: Date;
  lastLoginAt: Date;
}

// Check if user was created within last 5 minutes
const isRecentlyCreated = recent<User, 'createdAt'>({
  key: 'createdAt',
  minutes: 5,
});

// Check if user logged in within last 30 minutes
const isRecentlyActive = recent<User, 'lastLoginAt'>({
  key: 'lastLoginAt',
  minutes: 30,
});

const user = {
  id: 1,
  name: 'John',
  createdAt: new Date(),
  lastLoginAt: new Date(),
};

isRecentlyCreated(user); // true
isRecentlyActive(user); // true

// Use with filter
const users = [
  /* ... */
];
const recentUsers = users.filter(isRecentlyCreated);

Constants:

  • MS_PER_MINUTE - Milliseconds per minute (60,000)

✅ Validation Utilities

Type checking and validation helpers.

isAssigned<T>(value: T): boolean

Checks if a value is not null or undefined.

import { isAssigned } from '@raicamposs/toolkit';

isAssigned(0); // true
isAssigned(''); // true
isAssigned(false); // true
isAssigned(null); // false
isAssigned(undefined); // false

isNull(value: unknown): boolean

Checks if a value is strictly null.

import { isNull } from '@raicamposs/toolkit';

isNull(null); // true
isNull(undefined); // false
isNull(0); // false

isUndefined(value: unknown): boolean

Checks if a value is strictly undefined.

import { isUndefined } from '@raicamposs/toolkit';

isUndefined(undefined); // true
isUndefined(null); // false

isNullOrUndefined(value: unknown): boolean

Checks if a value is null or undefined.

import { isNullOrUndefined } from '@raicamposs/toolkit';

isNullOrUndefined(null); // true
isNullOrUndefined(undefined); // true
isNullOrUndefined(0); // false

isEmpty(value: unknown): boolean

Checks if a value is empty (null, undefined, empty string, or empty array).

import { isEmpty } from '@raicamposs/toolkit';

isEmpty(''); // true
isEmpty([]); // true
isEmpty(null); // true
isEmpty('hello'); // false
isEmpty([1, 2, 3]); // false

📦 Object Utilities

Object manipulation and transformation helpers.

clone<T>(obj: T): T

Deep clones an object.

import { clone } from '@raicamposs/toolkit';

const original = { name: 'John', address: { city: 'NYC' } };
const copy = clone(original);

copy.address.city = 'LA';
console.log(original.address.city); // 'NYC' (unchanged)

pickKeys<T, K>(obj: T, ...keys: K[]): Partial<T>

Creates a new object with only specified keys.

import { pickKeys } from '@raicamposs/toolkit';

const user = { id: 1, name: 'John', email: '[email protected]', age: 30 };
const publicData = pickKeys(user, 'id', 'name');
// Result: { id: 1, name: 'John' }

withoutKey<T, K>(obj: T, ...keys: K[]): Omit<T, K>

Creates a new object excluding specified keys.

import { withoutKey } from '@raicamposs/toolkit';

const user = { id: 1, name: 'John', password: 'secret' };
const safeUser = withoutKey(user, 'password');
// Result: { id: 1, name: 'John' }

purgeNullishValues(obj: any): any

Recursively removes null and undefined values from objects and arrays.

import { purgeNullishValues } from '@raicamposs/toolkit';

const data = {
  name: 'John',
  age: null,
  address: {
    city: 'NYC',
    zip: undefined,
  },
};

const cleaned = purgeNullishValues(data);
// Result: { name: 'John', address: { city: 'NYC' } }

hasOnlyUnassignedProperties(obj: unknown): boolean

Checks if an object has only unassigned (null or undefined) properties.

import { hasOnlyUnassignedProperties } from '@raicamposs/toolkit';

hasOnlyUnassignedProperties({ name: 'John', age: 30 }); // false
hasOnlyUnassignedProperties({ name: 'John', age: null }); // false
hasOnlyUnassignedProperties({ name: null, age: null }); // true
hasOnlyUnassignedProperties({}); // true

hasSomePropertyAssigned(obj: unknown): boolean

Checks if an object has some assigned properties.

import { hasSomePropertyAssigned } from '@raicamposs/toolkit';

hasSomePropertyAssigned({ name: 'John', age: null }); // true
hasSomePropertyAssigned({ name: null, age: null }); // false

🔤 String Utilities

String transformation and manipulation utilities.

StringUtils.toSnakeCase(str: string): string

Converts a string to snake_case.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.toSnakeCase('helloWorld'); // 'hello_world'
StringUtils.toSnakeCase('HelloWorld'); // 'hello_world'
StringUtils.toSnakeCase('hello-world'); // 'hello_world'

StringUtils.toKebabCase(str: string): string

Converts a string to kebab-case.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.toKebabCase('helloWorld'); // 'hello-world'
StringUtils.toKebabCase('HelloWorld'); // 'hello-world'

StringUtils.toCamelCase(str: string): string

Converts a string to camelCase.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.toCamelCase('hello_world'); // 'helloWorld'
StringUtils.toCamelCase('hello-world'); // 'helloWorld'

StringUtils.toTitleCase(str: string): string

Converts a string to Title Case.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.toTitleCase('hello world'); // 'Hello World'
StringUtils.toTitleCase('HELLO WORLD'); // 'Hello World'

StringUtils.slugify(text: string, separator?: string): string

Creates a URL-friendly slug from text.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.slugify('Hello World!'); // 'hello-world'
StringUtils.slugify('Café au Lait'); // 'cafe-au-lait'
StringUtils.slugify('Hello World', '_'); // 'hello_world'

StringUtils.removeAccents(text: string): string

Removes accents from characters.

import { StringUtils } from '@raicamposs/toolkit';

StringUtils.removeAccents('Olá, José!'); // 'Ola, Jose!'
StringUtils.removeAccents('Café'); // 'Cafe'

🔢 Number Utilities

Number formatting and rounding utilities.

roundABNT(value: number | string, fractionDigits?: number): number

Rounds numbers following ABNT (Brazilian) standards.

import { roundABNT } from '@raicamposs/toolkit';

roundABNT(1.335, 2); // 1.34 (rounds up when last digit is 5 followed by non-zero)
roundABNT(1.345, 2); // 1.34 (rounds to nearest even when 5 followed by zeros)
roundABNT(1.666, 2); // 1.67

ABNT Rounding Rules:

  • If digit after last kept digit is < 5: keep unchanged
  • If digit is > 5 or = 5 followed by non-zero: round up
  • If digit is = 5 followed by zeros: round to nearest even

📄 JSON Utilities

Safe JSON parsing and stringification.

JSONConverter.stringify(obj: any): string | null

Safely converts an object to JSON string.

import { JSONConverter } from '@raicamposs/toolkit';

JSONConverter.stringify({ name: 'John' }); // '{"name":"John"}'
JSONConverter.stringify(null); // null
JSONConverter.stringify(undefined); // null

JSONConverter.parse(json: string | null): object | undefined

Safely parses JSON string.

import { JSONConverter } from '@raicamposs/toolkit';

JSONConverter.parse('{"name":"John"}'); // { name: 'John' }
JSONConverter.parse('invalid json'); // undefined
JSONConverter.parse(null); // undefined
JSONConverter.parse(''); // undefined

JSONConverter.parseWithDefault(json: string | null, defaultValue?: any): any

Parses JSON with a fallback default value.

import { JSONConverter } from '@raicamposs/toolkit';

JSONConverter.parseWithDefault('{"name":"John"}', {}); // { name: 'John' }
JSONConverter.parseWithDefault('invalid', { name: 'Default' }); // { name: 'Default' }
JSONConverter.parseWithDefault(null, []); // []

🔀 Conditional Utilities

Conditional value helpers and null coalescing.

coalesce<T>(...values: T[]): T | undefined

Returns the first non-null, non-undefined value.

import { coalesce } from '@raicamposs/toolkit';

coalesce(null, undefined, 'hello', 'world'); // 'hello'
coalesce(null, undefined); // undefined
coalesce(0, null, 5); // 0 (0 is valid)

nullIf<T>(value: T, condition: boolean): T | null

Returns null if condition is true, otherwise returns the value.

import { nullIf } from '@raicamposs/toolkit';

nullIf('hello', true); // null
nullIf('hello', false); // 'hello'
nullIf(42, 42 === 0); // 42

undefinedIf<T>(value: T, condition: boolean): T | undefined

Returns undefined if condition is true, otherwise returns the value.

import { undefinedIf } from '@raicamposs/toolkit';

undefinedIf('hello', true); // undefined
undefinedIf('hello', false); // 'hello'

🎨 Type Utilities

TypeScript type helpers for better type safety.

Nullable<T>

Represents a value that can be null or undefined.

import { Nullable } from '@raicamposs/toolkit';

const name: Nullable<string> = null; // OK
const age: Nullable<number> = undefined; // OK
const active: Nullable<boolean> = true; // OK

Optional<T, K>

Makes specific properties of a type optional.

import { Optional } from '@raicamposs/toolkit';

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

type UserWithOptionalEmail = Optional<User, 'email'>;
// { id: number; name: string; email?: string; }

RequireAtLeastOne<T>

Requires at least one property from a type to be defined.

import { RequireAtLeastOne } from '@raicamposs/toolkit';

interface Contact {
  email: string;
  phone: string;
}

type ContactMethod = RequireAtLeastOne<Contact>;
// Must have at least email OR phone (or both)

const valid: ContactMethod = { email: '[email protected]' }; // OK
const invalid: ContactMethod = {}; // Error

Other Type Utilities

  • ValueOf<T> - Extracts value types from an object
  • Replace<T, R> - Replaces properties in a type with new ones
  • OmitNullableProperties<T> - Removes nullable properties from a type
  • Prettify<T> - Simplifies complex types for better readability
  • ObjectKeys<T> - Type-safe Object.keys() with proper typing
  • ObjectEntries<T> - Type-safe Object.entries() with proper typing
  • literal<T>(value) - Creates literal types from string values

🏗️ Builders

Builder patterns for constructing complex objects.

CompositeBuilder<T>

Fluent builder for applying transformations to objects.

import { CompositeBuilder } from '@raicamposs/toolkit';

interface User {
  name: string;
  email: string;
  isActive: boolean;
}

const builder = CompositeBuilder.new<User>()
  .add((user) => ({ ...user, email: user.email.toLowerCase() }))
  .add((user) => ({ ...user, isActive: true }));

const user = builder.build({
  name: 'John',
  email: '[email protected]',
  isActive: false,
});
// Result: { name: 'John', email: '[email protected]', isActive: true }

CompositeCriteria<T> & OrCriteria<T>

Composite pattern for building complex filtering logic.

import { CompositeCriteria, OrCriteria, Criteria } from '@raicamposs/toolkit';

class AgeCriteria implements Criteria<User> {
  matching(users: User[]): User[] {
    return users.filter((u) => u.age >= 18);
  }
}

class ActiveCriteria implements Criteria<User> {
  matching(users: User[]): User[] {
    return users.filter((u) => u.isActive);
  }
}

// AND logic
const composite = new CompositeCriteria<User>().add(new AgeCriteria()).add(new ActiveCriteria());

const filtered = composite.matching(users);

// OR logic
const orCriteria = new OrCriteria(new AgeCriteria(), new ActiveCriteria());

🎯 Entities

Domain entities with built-in validation.

CPF

Brazilian CPF (Cadastro de Pessoas Físicas) validation and formatting.

import { CPF } from '@raicamposs/toolkit';

const cpf = CPF.create('12345678909');
if (cpf.isRight()) {
  console.log(cpf.value.format()); // '123.456.789-09'
  console.log(cpf.value.toString()); // '12345678909'
}

CNPJ

Brazilian CNPJ (Cadastro Nacional da Pessoa Jurídica) validation and formatting.

import { CNPJ } from '@raicamposs/toolkit';

const cnpj = CNPJ.create('12345678000195');
if (cnpj.isRight()) {
  console.log(cnpj.value.format()); // '12.345.678/0001-95'
  console.log(cnpj.value.toString()); // '12345678000195'
}

Email

Email validation entity.

import { Email } from '@raicamposs/toolkit';

const email = Email.create('[email protected]');
if (email.isRight()) {
  console.log(email.value.toString()); // '[email protected]'
}

Phone

Brazilian phone number validation and formatting.

import { Phone } from '@raicamposs/toolkit';

const phone = Phone.create('11987654321');
if (phone.isRight()) {
  console.log(phone.value.format()); // '(11) 98765-4321'
  console.log(phone.value.toString()); // '11987654321'
}

📁 Project Structure

The toolkit is organized following Clean Architecture principles:

src/
├── utils/
│   ├── async/           # Async operations (sleep, retry)
│   ├── conditional/     # Conditional helpers (coalesce, nullIf)
│   ├── functional/      # Functional patterns (Either, mapOr)
│   ├── json/            # JSON utilities (JSONConverter)
│   ├── number/          # Number utilities (roundABNT)
│   ├── object/          # Object manipulation (clone, pick, purge)
│   ├── string/          # String transformations (StringUtils)
│   └── validation/      # Type checking (isNull, isEmpty)
├── types/               # TypeScript type utilities
├── entities/            # Domain entities
└── builders/            # Builder patterns

🧪 Testing

Run tests with coverage:

npm test              # Run tests in watch mode
npm run coverage      # Generate coverage report
npm run lint          # Check code quality
npm run lint:fix      # Auto-fix linting issues
npm run format        # Format code with Prettier
npm run format:check  # Check code formatting

📝 License

MIT © [raicamposs]


🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


📮 Support

For issues and questions, please open an issue on GitHub.