Как использовать профили из nartc / automapper в приложении nest js - PullRequest
1 голос
/ 25 апреля 2020

Я пытаюсь использовать AutoMapper для nodejs из nartc / automapper lib внутри проекта Nest JS, но у меня возникают проблемы при попытке использовать функциональность профилей. Вот моя конфигурация:

App.module

@Module({
  imports: [
    AutomapperModule.withMapper(),
  ],
  controllers: [],
  providers: [],
})
export class AppModule implements NestModule {}

Профиль

@Profile()
export class RoleProfile extends ProfileBase {
  constructor(@InjectMapper() mapper: AutoMapper) {
    super();

    mapper
      .createMap(Role, RoleWithPermissionDto)
      .forMember(
        dest => dest.id,
        mapFrom(src => src.id),
      )
      .forMember(
        dest => dest.name,
        mapFrom(src => src.name),
      )
      .forMember(
        dest => dest.created,
        mapFrom(src => src.createAt),
      )
      .forMember(dest => dest.permissions, ignore());
  }
}

Контроллер

@Controller('roles')
export class RolesController {
  constructor(private readonly rolesService: RolesService, @InjectMapper() private readonly mapper: AutoMapper) {}

  @Get()
  public async getRoles(@CurrentUser() user: CurrentUserDto) {
    const roles: Role[] = await this.rolesService.findByCompanyId(user.companyId);
    return this.mapper.mapArray(roles, RoleWithPermissionDto);
  }
}

Когда я вызываю действие моего контроллера ( getRoles), я получаю это сообщение об ошибке на консоли:

Mapping not found for source class Role extends base_entity_1.BaseEntity {
} and destination class RoleWithPermissionDto {
    static _OPENAPI_METADATA_FACTORY() {
        return { id: { required: false, type: () => Number }, name: { required: true, type: () => String }, permissions: { required: true, type: () => [require("../permissions/permission.dto").PermissionDto] }, createdAt: { required: true, 
type: () => Date }, created: { required: true, type: () => Date } };
    }
} +5034ms
Error: Mapping not found for source class Role extends base_entity_1.BaseEntity {
} and destination class RoleWithPermissionDto {
    static _OPENAPI_METADATA_FACTORY() {
        return { id: { required: false, type: () => Number }, name: { required: true, type: () => String }, permissions: { required: true, type: () => [require("../permissions/permission.dto").PermissionDto] }, createdAt: { required: true, 
type: () => Date }, created: { required: true, type: () => Date } };
    }
}
    at getMappingForDestination (D:\trabajo\cencogan\project-mercury-api\node_modules\@nartc\automapper\dist\automapper.cjs.development.js:131:11)
    at AutoMapper.mapArray$1 [as mapArray] (D:\trabajo\cencogan\project-mercury-api\node_modules\@nartc\automapper\dist\automapper.cjs.development.js:1262:19)
    at RolesController.getRoles (D:\trabajo\cencogan\project-mercury-api\dist\src\roles\roles.controller.js:35:28)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Если я решу создать сопоставление непосредственно внутри контроллера, все будет работать как положено. например:

@Controller('roles')
export class RolesController {
  constructor(private readonly rolesService: RolesService, @InjectMapper() private readonly mapper: AutoMapper) {}

  @Get()
  public async getRoles(@CurrentUser() user: CurrentUserDto) {
    const roles: Role[] = await this.rolesService.findByCompanyId(user.companyId);
    this. mapper
      .createMap(Role, RoleWithPermissionDto)
      .forMember(
        dest => dest.id,
        mapFrom(src => src.id),
      )
      .forMember(
        dest => dest.name,
        mapFrom(src => src.name),
      )
      .forMember(
        dest => dest.created,
        mapFrom(src => src.createAt),
      )
      .forMember(dest => dest.permissions, ignore());
    return this.mapper.mapArray(roles, RoleWithPermissionDto);
  }
}

Я предположил, что мой профиль не вызывается, кто-нибудь использовал эту библиотеку в проекте Nest JS?

Я использую функциональные модули, поэтому мой контроллер зарегистрирован внутри RolesModule.

Буду благодарен за любую помощь

Ответы [ 2 ]

0 голосов
/ 26 апреля 2020

Я являюсь автором @nartc/automapper и nestjsx-automapper, и кажется, что вы уже используете nestjsx-automapper.

Я не вижу ничего плохого в вашей настройке. Однако из-за ограничения TypeScript, если у вас есть Profile (в данном случае RoleProfile) в отдельном файле, тогда у вас есть для импорта RoleProfile в другой файл, который WILL будет гарантированно исполнен (Module - лучшее место)

import './role.profile';

@Module(...)
export class RoleModule {}

Если вы хотите выделить Profile в отдельный файл, то вам необходимо убедиться, что файл запускается путем его импорта куда-то (опять же, модуль - хорошее место).

Я упоминал об этом фрагменте в README, но, кажется, он недостаточно выделен, чтобы привлечь внимание людей.

Другая вещь в вашем Profile конструкторе, вам не нужно @InjectMapper, поскольку mapper будет передано вам, когда nestjsx-automapper выполнит mapper.addProfile() внутри.

Приносим извинения за доставленные неудобства.

0 голосов
/ 25 апреля 2020

Вы можете использовать NestJSX Automapper , это обертка вокруг @ nartc / automapper для использования с Nest JS в качестве модуля.

...