A easy to use way to map any ugly backend structures into clean TypeScript/ES6 models.
Inspired typestack class-transformer
Made with ❤️ by w3tech
Are you tired of ugly and weird backend structures which makes it challenging to work with in your application 🤯? Here comes a solution 🎉! Just use class-mapper to map all weird structures into TypeScript and ES6 models 👉 YOU 🤗 like to work with in your web frontend or Node.js application and not backend guys 🤪.
Try it!! We are happy to hear your feedback or any kind of new features.
npm install class-mapper --save
or with yarn
yarn add class-mapper
<html>
<head>
<script src="node_modules/class-mapper/dist/class-mapper.js"></script>
</head>
</html>
This method maps a source class to your target class
import {mapClasses, MapFromSource, PropertyType} from 'class-mapper';
/**
* Source classes
*/
abstract class SourcePersonModel {
public name1: string;
public name2: string;
}
class SourceCarModel {
public attribute1: string;
public attribute2: string;
}
class SourceCustomerModel extends SourcePersonModel {
public car1!: SourceCarModel[];
}
const sourceUser: SourceCustomerModel = new SourceCustomerModel();
/**
* Target classes
*/
abstract class TargetPersonModel {
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.name1)
public firstName!: string;
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.name2)
public lastName!: string;
}
class TargetCarModel {
@MapFromSource((sourceCar: SourceCarModel) => sourceCar.attribute1)
public manufacturer!: string;
@MapFromSource(sourceCar: SourceCarModel) => sourceCar.attribute2)
public model!: string;
}
class TargetCustomerModel extends TargetPersonModel {
@PropertyType(TargetCarModel)
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.car1)
public cars!: TargetCarModel[];
}
const targetUser: TargetCustomerModel = mapClasses(TargetCustomerModel, sourceUser);
With groups
array, you can exclude properties from mapping. MapFromSource
decorators with no groups
option will always be mapped.
import {mapClasses, MapFromSource, PropertyType} from 'class-mapper';
/**
* Source class
*/
abstract class SourcePersonModel {
public name1: string;
public name1: string;
}
/**
* Target class
*/
const firstNameOnly = 'first-name-only';
const lastNameOnly = 'last-name-only';
abstract class TargetPersonModel {
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.name1, { groups: [firstNameOnly] })
public firstName!: string;
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.name2, { groups: [lastNameOnly] })
public lastName!: string;
}
const targetUser: TargetCustomerModel = mapClasses(TargetCustomerModel, sourceUser, { groups: [lastNameOnly] });
With enabled
you can exclude conditionally properties. MapFromSource
decorators with no enabled
option will always be mapped.
import {mapClasses, MapFromSource, PropertyType} from 'class-mapper';
/**
* Source class
*/
abstract class SourcePersonModel {
public name1: string;
public name1: string;
}
/**
* Target class
*/
abstract class TargetPersonModel {
@MapFromSource((sourceUser: SourcePersonModel) => sourceUser.name1, { enabled: (sourceUser: SourcePersonModel) => !!sourceUser.name1 })
public firstName!: string;
@MapFromSource(sourceUser => sourceUser.name2, { enabled: (sourceUser: SourcePersonModel) => !!sourceUser.name2 })
public lastName!: string;
}
const targetUser: TargetCustomerModel = mapClasses(TargetCustomerModel, sourceUser);