An open API service indexing awesome lists of open source software.

https://github.com/twistezo/ts-dto-mapper

DTO (Data Transfer Object) to Object Model transformer
https://github.com/twistezo/ts-dto-mapper

data dto map mapper model object transfer transform transformer typescript

Last synced: 5 months ago
JSON representation

DTO (Data Transfer Object) to Object Model transformer

Awesome Lists containing this project

README

          

# DTO mapper based on TS types

![](https://img.shields.io/npm/v/@twistezo/ts-dto-mapper?style=flat-square&color=9cf)
![](https://img.shields.io/npm/dt/@twistezo/ts-dto-mapper?style=flat-square&color=9cf)
![](https://img.shields.io/npm/l/@twistezo/ts-dto-mapper?style=flat-square&color=yellow)

[![Build and test](https://github.com/twistezo/ts-dto-mapper/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/twistezo/ts-dto-mapper/actions/workflows/build.yml?query=branch:main)

## Description

Utility for easy mapping between DTO and OM objects based on their data types.

Benefits:

- no object-oriented approach based on classes
- no cluttering the code with decorators
- no need to install a large library for a simple operation
- only function based on objects types with access to the context inside

## Knowledge

DTO - Data Transfer Object

- ex. object shape from API
- https://en.wikipedia.org/wiki/Data_transfer_object

OM - Object Model

- various shape of object, ex. business object
- https://en.wikipedia.org/wiki/Object_model

## Setup

```
npm install @twistezo/ts-dto-mapper
```

## Tips

- Always populate generic types ``, and `` in `mapDTO` function. This helps you with debugging and provides IDE IntelliSense.

- `.transform` accepts callback with source context so you can put there reusable data transformation and have reusable mapper.

## Usage

### tldr;

From DTO (one-way):

```ts
const foo = mapDTO({
from: fooDTO,
}).transform(fooDTO => ({
// map with access to source context
}))
```

To DTO (one-way):

```ts
const fooDTO = mapDTO({
from: foo,
}).transform(foo => ({
// map with access to source context
}))
```

Bidirectional (both ways at once):

```ts
const { from, to } = mapDTO({
from: fooDTO,
})
.reverse(foo) // reverse source
.transform(
fooDTO => ({
// DTO -> OM
}),
foo => ({
// OM -> DTO
}),
)
```

### Full example

Import:

```ts
import { mapDTO } from '@twistezo/ts-dto-mapper'
```

Prepare OM and DTO shapes:

```ts
type Foo = {
id: string
firstName: string
lastName: string
}

type FooDTO = {
uuid: number
fullName: string
unnecessary: object
}
```

Prepare objects:

```ts
const foo: Foo = {
id: '1001',
firstName: 'John',
lastName: 'Smith',
}

const fooDTO: FooDTO = {
uuid: 1001,
fullName: 'John Smith',
unnecessary: {},
}
```

Map from DTO to OM:

```ts
const fooFromFooDTO: Foo = mapDTO({
from: fooDTO,
}).transform((fooDTO: FooDTO): Foo => {
// map with access to source context

const { fullName, uuid } = fooDTO
const [firstName, lastName] = fullName.split(' ')

return {
id: uuid.toString(),
firstName,
lastName,
}
})
```

Map from OM to DTO:

```ts
const fooDTOfromFoo: FooDTO = mapDTO({ from: foo }).transform(foo => {
// map with access to source context

const { firstName, id, lastName } = foo

return {
uuid: Number(id),
fullName: `${firstName} ${lastName}`,
unnecessary: {},
}
})
```

#### Bidirectional mapping

When you need to transform objects in both directions simultaneously, use the `.reverse()` method:

```ts
const { from, to } = mapDTO({ from: fooDTO })
.reverse(foo)
.transform(
// Forward: FooDTO -> Foo
(fooDTO: FooDTO): Foo => {
const { fullName, uuid } = fooDTO
const [firstName, lastName] = fullName.split(' ')

return {
id: uuid.toString(),
firstName,
lastName,
}
},
// Reverse: Foo -> FooDTO
(foo: Foo): FooDTO => {
const { firstName, id, lastName } = foo

return {
uuid: Number(id),
fullName: `${firstName} ${lastName}`,
unnecessary: {},
}
},
)
```