NestJS integration for @ilhamtahir/ts-mapper - A MapStruct-like object mapping library for TypeScript
npm install @ilhamtahir/nestjs-mapper



NestJS integration for @ilhamtahir/ts-mapper - A MapStruct-like object mapping library for TypeScript and NestJS.
``bashInstall both packages
npm install @ilhamtahir/ts-mapper @ilhamtahir/nestjs-mapper
🚀 Features
- NestJS Integration: Seamless dependency injection support
- Auto Registration: Automatic mapper registration in DI container
- Enhanced Decorators: NestJS-specific decorator enhancements
- Module Configuration: Easy module setup with
MapperModule
- Proxy Support: Automatic proxy creation for abstract mappers📖 Quick Start
$3
`typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { MapperModule } from '@ilhamtahir/nestjs-mapper';@Module({
imports: [
MapperModule.forRoot(), // Auto-register all @Mapper() classes
],
})
export class AppModule {}
`$3
`typescript
// user.mapper.ts
import { Mapper, Mapping, transform } from '@ilhamtahir/nest-mapper';@Mapper()
export class UserMapper {
@Mapping({ source: 'fullName', target: 'name' })
@Mapping({ source: 'profile.bio', target: 'bio' })
@Mapping({ source: 'profile.avatar', target: 'avatar' })
toDto(entity: UserEntity): UserDto {
return transform(this, 'toDto', entity, UserDto);
}
}
`$3
`typescript
// user.service.ts
import { Injectable } from '@nestjs/common';
import { UserMapper } from './mappers/user.mapper';@Injectable()
export class UserService {
constructor(private readonly userMapper: UserMapper) {}
async getUser(id: number): Promise {
const entity = await this.userRepository.findById(id);
return this.userMapper.toDto(entity);
}
async getUsers(): Promise {
const entities = await this.userRepository.findAll();
return entities.map(entity => this.userMapper.toDto(entity));
}
}
`🆕 Abstract Class Support
$3
`typescript
// user-abstract.mapper.ts
import { Mapper, Mapping } from '@ilhamtahir/nest-mapper';@Mapper()
export abstract class UserAbstractMapper {
/**
* Empty method body: system will automatically call transform
*/
@Mapping({ source: 'fullName', target: 'name' })
@Mapping({ source: 'profile.bio', target: 'bio' })
@Mapping({ source: 'profile.avatar', target: 'avatar' })
toDto(entity: UserEntity): UserDto {
// Empty method body, system will automatically call transform
return {} as UserDto;
}
/**
* Custom method with business logic
*/
toDtoWithCustomLogic(entity: UserEntity): UserDto {
const dto = this.toDto(entity); // Calls auto-mapping
// Add custom logic
dto.displayName =
${dto.name} (${entity.age} years old);
dto.isActive = entity.lastLoginAt > new Date(Date.now() - 30 24 60 60 1000); return dto;
}
}
`$3
`typescript
// advanced-user.mapper.ts
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Mapper, Mapping, transform } from '@ilhamtahir/nest-mapper';@Mapper()
@Injectable()
export class AdvancedUserMapper {
constructor(
private readonly configService: ConfigService,
private readonly logger: Logger
) {}
@Mapping({ source: 'fullName', target: 'name' })
toDto(entity: UserEntity): UserDto {
this.logger.log(
Mapping user: ${entity.id}); const dto = transform(this, 'toDto', entity, UserDto);
// Use injected services
const baseUrl = this.configService.get('app.baseUrl');
dto.avatarUrl =
${baseUrl}/avatars/${dto.avatar}; return dto;
}
}
`🔧 Advanced Configuration
$3
`typescript
// app.module.ts
@Module({
imports: [
MapperModule.forRoot({
// Custom configuration options (if available in future versions)
}),
],
})
export class AppModule {}
`$3
`typescript
// user.module.ts
import { Module } from '@nestjs/common';
import { MapperModule } from '@ilhamtahir/nest-mapper';
import { UserMapper } from './mappers/user.mapper';
import { UserService } from './user.service';@Module({
imports: [MapperModule], // Import without forRoot() in feature modules
providers: [UserService, UserMapper],
exports: [UserService, UserMapper],
})
export class UserModule {}
`🔧 Troubleshooting
$3
`typescript
// Make sure to import MapperModule in your app module
@Module({
imports: [
MapperModule.forRoot(), // This is required!
],
})
export class AppModule {}
`$3
`typescript
// Use forwardRef for circular dependencies
@Injectable()
export class UserService {
constructor(
@Inject(forwardRef(() => UserMapper))
private readonly userMapper: UserMapper
) {}
}
`📚 API Documentation
$3
-
MapperModule.forRoot(): Configure and register the mapper module$3
-
@Mapper(): Mark class as mapper and register in NestJS DI container
- @Mapping({ source, target }): Explicit field mapping definition$3
-
transform(mapper, method, input, OutputType)`: Execute mapping transformation- Full Documentation
- Core Package (@ilhamtahir/ts-mapper)
- FAQ
- Performance Guide
- Contributing Guide
- Changelog
- @ilhamtahir/ts-mapper: Core mapping functionality
MIT License