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 🙏

© 2024 – Pkg Stats / Ryan Hefner

transmutant

v4.0.0

Published

Powerful type transmutations for TypeScript 🧬

Downloads

507

Readme

🧬 Transmutant 🧬

A powerful, type-safe TypeScript library for transmuting objects through flexible schema definitions.

npm version License: MIT GitHub issues GitHub stars

Features

  • 🔒 Type-safe: Full TypeScript support with strong type inference
  • 🎯 Flexible mapping: Direct property mapping or custom transmuter functions
  • High performance: Minimal overhead and zero dependencies
  • 🔄 Extensible: Support for custom transmutation logic and external data
  • 📦 Lightweight: Zero dependencies, small bundle size
  • 🛠️ Predictable: Transparent handling of undefined values

Installation

npm install transmutant

Quick Start

import { Schema, transmute } from 'transmutant'

// Source type
interface User {
  firstName: string;
  lastName: string;
  email: string;
}

// Target type
interface UserDTO {
  fullName: string;
  contactEmail: string;
}

// Define transmutation schema
const schema: Schema<User, UserDTO>[] = [
  {
    to: 'fullName',
    from: ({ source }) => `${source.firstName} ${source.lastName}`
  },
  {
    to: 'contactEmail',
    from: 'email'
  }
]

// Transmute the object
const user: User = {
  firstName: 'John',
  lastName: 'Doe',
  email: '[email protected]'
}

const userDTO = transmute(schema, user)
// Result: { fullName: 'John Doe', contactEmail: '[email protected]' }

Core Concepts

Schema Definition

A schema is an array of transmutation rules that define how properties should be mapped from the source to the target type. Each rule specifies:

  • The target property key (to)
  • Either a source property key for direct mapping or a transmuter function (from)
type Schema<Source, Target, Extra> = {
  to: keyof Target,
  from: keyof Source | Transmuter<Source, Target, Extra>
}

Transmutation Types

1. Direct Property Mapping

Map a property directly from source to target when types are compatible:

interface Source {
  email: string;
}

interface Target {
  contactEmail: string;
}

const schema: Schema<Source, Target>[] = [
  { to: 'contactEmail', from: 'email' }
]

2. Custom Transmuter Functions

Transmute properties using custom logic with full type safety:

interface Source {
  age: number;
}

interface Target {
  isAdult: boolean;
}

const schema: Schema<Source, Target>[] = [
  {
    to: 'isAdult',
    from: ({ source }) => source.age >= 18
  }
];

3. External Data Transmutations

Include additional context in transmutations through the extra parameter:

interface Source {
  city: string;
  country: string;
}

interface Target {
  location: string;
}

interface ExtraData {
  separator: string;
}

const schema: Schema<Source, Target, ExtraData>[] = [
  {
    to: 'location',
    from: ({ source, extra }) =>
      `${source.city}${extra.separator}${source.country}`
  }
];

const result = transmute(schema,
  { city: 'New York', country: 'USA' },
  { separator: ', ' }
);
// Result: { location: 'New York, USA' }

API Reference

Types

// Arguments passed to a mutation function
type TransmuterArgs<Source, Extra> = { source: Source, extra?: Extra }

// Function that performs a custom transmutation
type Transmuter<Source, Target, Extra> = (args: TransmuterArgs<Source, Extra>) => Target[keyof Target]

// Defines how a property should be transmuted
type Schema<Source, Target, Extra> = {
  to: keyof Target,
  from: keyof Source | Transmuter<Source, Target, Extra>
}

transmute()

Main function for performing object transmutations.

function transmute<Source, Target, Extra>(
  schema: Schema<Source, Target, Extra>[],
  source: Source,
  extra?: Extra
): Target;

Parameters

| Parameter | Type | Description | |-----------|-----------------------------------|------------------------------------| | schema | Schema<Source, Target, Extra>[] | Array of transmutation rules | | source | Source | Source object to transmute | | extra | Extra (optional) | Additional data for transmutations |

Returns

Returns an object of type Target with all specified transmutations applied.

Type Safety Examples

The library provides strong type checking for both direct mappings and custom transmutations:

interface Source {
  firstName: string;
  lastName: string;
  age: number;
}

interface Target {
  fullName: string;
  isAdult: boolean;
}

// Correct usage - types match
const validSchema: Schema<Source, Target>[] = [
  {
    to: 'fullName',
    from: ({ source }) => `${source.firstName} ${source.lastName}`  // Returns string
  },
  {
    to: 'isAdult',
    from: ({ source }) => source.age >= 18  // Returns boolean
  }
];

// Type error - incorrect return type
const invalidSchema: Schema<Source, Target>[] = [
  {
    to: 'isAdult',
    from: ({ source }) => source.age  // Error: number not assignable to boolean
  }
];

Contributing

Contributions are welcome! Feel free to submit a Pull Request.

License

MIT © Antoni Oriol