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

dto-mapper

v0.2.3

Published

Simple to use library to map DTO using typescript decorators

Downloads

412

Readme

dto-mapper

SImple to use library to map DTO using typescript decorators

NPM Version Circle CI

Install

This node module is available through npm.

This package is meant to be used inside a Typescript project as it leverages decorators to work.

npm i dto-mapper

This package has a peer dependency to reflect-metadata and will require it to function properly. It can be installed from npm using the following command:

npm i reflect-metadata

You will need to enable experimental decorators and emitting decorator metadata inside your tsconfig.json:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Usage

Defining DTOs

@dto()
export class UserDto {

    @include()
    id: number;

    @include()
    email: string;
}

DTOs must be annotated by @dto() in order to be accepted by the builder function.

Child class inheriting from class annotated by @dto() must also be explicitly decorated by the @dto().

Every field that need to be mapped inside the DTO must be explicitly decorated by @include() or they will be ignored by default.

Binding fields

By default fields from the DTO will expect a field with the same name inside the object being serialized. When being deserialized they will also map to a field with the same name by default.

For example the above DTO will expect an object similar to:

const toSerialize = {
    id: 0,
    email: "[email protected]",
};

There are various decorators available to customize this behavior:

@mapTo

This decorator allows to define the name of the field the property is mapped to.

Example:

@dto()
export class UserDto {

    @include()
    id: number;

    @include()
    @mapTo('userEmail')
    email: string;
}

This DTO will expect an object similar to:

const toSerialize = {
    id: 0,
    userEmail: "[email protected]",
};

@accessMode

This decorator allows to restrict the access to the property, it accepts a value from the AccessMode enum:

| Value | Effect | | ----- | ------ | | AccessMode.NONE | Property will be ignored. | | AccessMode.READ | Property will be only serialized but not deserialized. | | AccessMode.WRITE | Property will be only deserialized but not serialized. | | AccessMode.ALL (default) | Property will be ignored. |

@readOnly

Shortcut for @accessMode(AccessMode.READ)

@writeOnly

Shortcut for @accessMode(AccessMode.WRITE)

@transform

Allows to modify a property before serializing and deserializing it.

Example:

@dto()
export class UserDto {

    @include()
    id: number;

    @include()
    @transform({
        toDto: (name) => name.toUpperCase(),
        fromDto: (name) => name.toLowerCase(),
    })
    name: string;
}

In this example the name property will be serialized in uppercase but will be deserialized in lowercase.

@scope

Defines the scopes that can access this property. The scope can be passed to the mapper when serializing or deserializing.

This can be used to hide fields to user with insufficient permissions

Example:

@dto()
export class UserDto {

    @include()
    id: number;

    @include()
    @scope('admin', 'moderator')
    name: string;
}

In this example the name property will only be serialized and deserialized if the 'admin' OR the 'moderator' scope is passed to the mapper.

@nested

Allows to map a property to another DTO.

Example:

@dto()
export class RoleDto {

    @include()
    name: string;
}

@dto()
export class UserDto {

    @include()
    id: number;

    @include()
    @nested(
        () => RoleDto,
        true /* Set to true if this is an array otherwise false */
    )
    roles: RoleDto[];
}

In this example the UserDto includes an array of RoleDto.

Creating the mapper

Once your DTO class has been defined you can create a mapper to actually start serializing and deserializing data.

In order to do so you can use the buildMapper function.

Example:

const mapper = buildMapper(UserDto); // Magic !

Important: this function is expensive and should be called only once per DTO, you should cache the mapper and reuse it.

Mapping data

Finally, when your mapper is ready you can call the serialize method to serialize data:

// No scope
const serialized = mapper.serialize({ id: 0, userEmail: '[email protected]' });

// Admin scope
const serializedWithScope = mapper.serialize({ id: 0, userEmail: '[email protected]' }, 'admin');

You can deserialize data using the deserialize method:

// No scope
const deserialized = mapper.deserialize({ id: 0, email: '[email protected]' });

// Admin scope
const deserializedWithScope = mapper.deserialize({ id: 0, email: '[email protected]' }, 'admin');

License

MIT