Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
transmutant
Advanced tools
A powerful, type-safe TypeScript library for transforming objects through flexible schema definitions.
npm install transmutant
import { transmute, Schema } from 'transmutant';
// Source type
interface User {
firstName: string;
lastName: string;
email: string;
}
// Target type
interface UserDTO {
fullName: string;
contactEmail: string;
}
// Define transformation schema
const schema: Schema<User, UserDTO>[] = [
{
to: 'fullName',
from: ({ source }) => `${source.firstName} ${source.lastName}`
},
{
from: 'email',
to: 'contactEmail'
}
];
// Transform the object
const user: User = {
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com'
};
const userDTO = transmute(schema, user);
// Result: { fullName: 'John Doe', contactEmail: 'john@example.com' }
A schema is an array of transformation rules that define how properties should be mapped from the source to the target type. Each rule specifies the target property key and either a source property key for direct mapping or a transformation function that produces the correct type for that target property.
type Schema<Source, Target, TExtra = unknown> = {
[TargetKey in keyof Target]: {
/** Target property key */
to: TargetKey
/** Source property key for direct mapping or a custom transformation function */
from: keyof Source | TransmuteFn<Source, Target, TargetKey, TExtra>
}
}[keyof Target]
Map a property directly from source to target:
interface Source {
email: string;
}
interface Target {
contactEmail: string;
}
const schema: Schema<Source, Target>[] = [
{ from: 'email', to: 'contactEmail' }
];
Transform properties using custom logic with type safety:
interface Source {
age: number;
}
interface Target {
isAdult: boolean;
}
const schema: Schema<Source, Target>[] = [
{
to: 'isAdult',
from: ({ source }) => source.age >= 18
}
];
Include additional context in transformations:
interface Source {
price: number;
}
interface Target {
formattedPrice: string;
}
interface ExtraData {
currency: string;
}
const schema: Schema<Source, Target, ExtraData>[] = [
{
to: 'formattedPrice',
from: ({ source, extra }) =>
`${source.price.toFixed(2)} ${extra.currency}`
}
];
When a source property doesn't exist or a transformation function returns undefined, the target property will remain undefined:
interface Source {
existingField: string;
}
interface Target {
mappedField: string;
computedField: string;
}
const schema: Schema<Source, Target>[] = [
{
from: 'nonExistentField' as keyof Source, // Property doesn't exist
to: 'mappedField'
},
{
to: 'computedField',
from: ({ source }) => undefined // Transformation returns undefined
}
];
const result = transmute(schema, { existingField: 'value' });
// Result: { mappedField: undefined, computedField: undefined }
This allows you to:
undefined
) and explicitly set null valuestransmute<Source, Target, TExtra = unknown>
Main transformation function.
Parameter | Type | Description |
---|---|---|
schema | Schema<Source, Target, TExtra>[] | Array of transformation rules |
source | Source | Source object to transform |
extra? | TExtra | Optional additional data |
Returns an object of type Target
.
/**
* Schema entry defining how a property should be transformed
*/
type Schema<Source, Target, TExtra = unknown> = {
[TargetKey in keyof Target]: {
/** Target property key */
to: TargetKey
/** Source property key for direct mapping or a custom transformation function */
from: keyof Source | TransmuteFn<Source, Target, TargetKey, TExtra>
}
}[keyof Target]
/**
* Function that performs property transformation
*/
type TransmuteFn<Source, Target, TargetKey extends keyof Target, TExtra = unknown> =
(args: TransmuteFnArgs<Source, TExtra>) => Target[TargetKey]
/**
* Arguments passed to transformation function
*/
type TransmuteFnArgs<Source, TExtra> = {
source: Source
extra?: TExtra
}
interface Source {
firstName: string;
lastName: string;
age: number;
}
interface Target {
fullName: string; // TargetKey = 'fullName', type = string
isAdult: boolean; // TargetKey = 'isAdult', type = boolean
}
// TypeScript enforces correct return types
const schema: Schema<Source, Target>[] = [
{
to: 'fullName',
from: ({ source }) => `${source.firstName} ${source.lastName}` // Must return string
},
{
to: 'isAdult',
from: ({ source }) => source.age >= 18 // Must return boolean
}
];
// Type error example:
const invalidSchema: Schema<Source, Target>[] = [
{
to: 'isAdult',
from: ({ source }) => source.age // Type error: number is not assignable to boolean
}
];
When using direct property mapping, TypeScript ensures type compatibility:
interface Source {
email: string;
age: number;
}
interface Target {
contactEmail: string;
yearOfBirth: number;
}
const schema: Schema<Source, Target>[] = [
{ from: 'email', to: 'contactEmail' }, // OK: string -> string
{ from: 'age', to: 'yearOfBirth' } // OK: number -> number
];
Extra data is fully typed:
interface ExtraData {
currentYear: number;
}
interface Source {
age: number;
}
interface Target {
yearOfBirth: number;
}
const schema: Schema<Source, Target, ExtraData>[] = [
{
to: 'yearOfBirth',
from: ({ source, extra }) => extra.currentYear - source.age
}
];
const result = transmute(schema, { age: 25 }, { currentYear: 2024 });
Contributions are welcome! Feel free to submit a Pull Request.
MIT © Antoni Oriol
FAQs
Powerful type transmutations for TypeScript 🧬
The npm package transmutant receives a total of 2 weekly downloads. As such, transmutant popularity was classified as not popular.
We found that transmutant demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.