Mapper
Mapper
Mapper is the main character in AutoMapper TypeScript. Everything starts with a Mapper. To create a Mapper, call createMapper() along with a Strategy
const mapper = createMapper({
strategyInitializer: classes(),
});
MappingStrategy
In order for Mapper to map properties, Mapper needs to know about the properties' metadata. That's what the Strategy provides to the Mapper. A Strategy deals with:
- Discover the metadata: Based on the user input, a strategy needs to know how to discover the metadata of the models from that input. E.g:
@automapper/classescan discover the metadata with@AutoMapdecorator. - Retrieve the metadata: A strategy has its own "storage" to store the raw metadata. In order for
Mapperto work consistently, a Strategy needs to provide a way to retrieve this metadata in the shape thatMappercan understand. E.g:@automapper/classesstores the metadata inReflectobject. - Apply the metadata: By default,
Mapperknows how to apply the metadata for a specific model. However, the consumers can customize this behavior by passing in a customapplyMetadatafunction.
In addition to dealing with metadata, a Strategy also provides two hooks:
preMap: Runs before the map operation starts. This step is usually to prepare thesourceObjectbefore it goes into themapoperation.postMap: Runs after the map operation starts. This step is usually to massage the resultdestinationObjectbefore it gets returned to the user.
Official Strategies
AutoMapper TypeScript comes with 4 official strategies:
| package | strategy | description |
|---|---|---|
@automapper/classes | classes() | Works with TS/ES6 Classes |
@automapper/pojos | pojos() | Works with Interfaces/Types |
@automapper/mikro | mikro() | Works with TS/ES6 Classes and MikroORM |
@automapper/sequelize | sequelize() | Works with TS/ES6 Classes and Sequelize |
info
mikro() and sequelize() are extensions of classes(). They call classes() with different MappingStrategyInitializerOptions
Logger
AutoMapper TypeScript exposes a logger via the symbol AutoMapperLogger. There are 4 log levels:
logwarninfoerror
By default, these log levels are implemented using the console's counterparts in addition to having [AutoMapper] as the prefix.
console.log('some log'); // some log
AutoMapperLogger.log('some log'); // [AutoMapper]: some log
Customization
We can customize AutoMapperLogger via AutoMapperLogger.configure()
// in your application's entry point, at the top
AutoMapperLogger.configure({
warn: null, // nullify "warn" completely
});
There is one caveat in terms of customizing AutoMapperLogger which is having to call AutoMapperLogger.configure() as soon as possible so we need to pick a file that is guaranteed to run early, preferably earlier than decorators.
- In NestJS, this can be
app.module.ts - In Angular, this can be
polyfills.ts
The caveat stems from the fact that @AutoMap decorator from @automapper/classes does have a AutoMapperLogger.warn call when it fails to infer the type from Reflection. This might not be a desired behavior in certain environments.