Skip to content

Commit

Permalink
feat(core): add autoMap mapping configuration (#538)
Browse files Browse the repository at this point in the history
Avoid using the @AutoMap decorator by replacing it with calls to
autoMap inside the profile.
  • Loading branch information
gabrielkim13 authored Mar 10, 2023
1 parent 25b5e7a commit 5906add
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from './lib/mapping-configurations/before-map';
export * from './lib/mapping-configurations/after-map';
export * from './lib/mapping-configurations/extend';
export * from './lib/mapping-configurations/naming-conventions';
export * from './lib/mapping-configurations/auto-map';

export * from './lib/member-map-functions/map-from';
export * from './lib/member-map-functions/map-with';
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/lib/mapping-configurations/auto-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { MappingConfiguration } from '../types';
import { mapFrom } from '../member-map-functions/map-from';

import { forMember } from './for-member';

export function autoMap<
TSource extends { [key in TKey]: TValue },
TDestination extends { [key in TKey]: TValue },
TKey extends keyof TSource & keyof TDestination,
TValue extends TSource[TKey] & TDestination[TKey]
>(prop: TKey): MappingConfiguration<TSource, TDestination> {
return forMember(
(dest) => dest[prop] as TValue,
mapFrom((src) => src[prop])
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class DecoratorlessUserDto {
firstName!: string;
lastName!: string;
fullName!: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { classes } from '@automapper/classes';
import { addProfile, createMapper } from '@automapper/core';

import { DecoratorlessUserDto } from './dtos/decoratorless-user.dto';
import { DecoratorlessUser } from './models/decoratorless-user';
import { decoratorlessUserProfileFactory } from './profiles/decoratorless-user.profile';

describe('Map Without Decorators', () => {
const mapper = createMapper({ strategyInitializer: classes() });

beforeAll(() => {
addProfile(mapper, decoratorlessUserProfileFactory());
});

it('should map model to DTO', async () => {
const dto = await mapper.mapAsync(
new DecoratorlessUser('Gabriel', 'Kim'),
DecoratorlessUser,
DecoratorlessUserDto
);

expect(dto.firstName).toEqual('Gabriel');
expect(dto.lastName).toEqual('Kim');
expect(dto.fullName).toEqual('Gabriel Kim');
});

it('should map DTO to model', async () => {
const dto = new DecoratorlessUserDto();
dto.firstName = 'Gabriel';
dto.lastName = 'Kim';
dto.fullName = 'Gabriel Kim';

const model = await mapper.mapAsync(
dto,
DecoratorlessUserDto,
DecoratorlessUser
);

expect(model.firstName).toEqual('Gabriel');
expect(model.lastName).toEqual('Kim');
expect(model).not.toHaveProperty('fullName');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class DecoratorlessUser {
firstName!: string;
lastName!: string;

constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
autoMap,
createMap,
forMember,
mapFrom,
MappingProfile,
} from '@automapper/core';
import { DecoratorlessUserDto } from '../dtos/decoratorless-user.dto';
import { DecoratorlessUser } from '../models/decoratorless-user';

export function decoratorlessUserProfileFactory(): MappingProfile {
return (mapper) => {
createMap(
mapper,
DecoratorlessUser,
DecoratorlessUserDto,
autoMap('firstName'),
autoMap('lastName'),
forMember(
(d) => d.fullName,
mapFrom((s) => s.firstName + ' ' + s.lastName)
)
);

createMap(
mapper,
DecoratorlessUserDto,
DecoratorlessUser,
autoMap('firstName'),
autoMap('lastName')
);
};
}

0 comments on commit 5906add

Please sign in to comment.