Skip to content

Commit

Permalink
fix(core): ensure forMember (custom) will always override forSelf
Browse files Browse the repository at this point in the history
  • Loading branch information
Chau Tran authored and Chau Tran committed Aug 27, 2021
1 parent 02ecd24 commit ef7471a
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 22 deletions.
34 changes: 21 additions & 13 deletions packages/core/src/lib/create-mapper/apply-type-converters.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import type {
PrimitiveConstructorWithDate,
ValueSelector,
} from '@automapper/types';
import { MapFnClassId, MappingPropertiesClassId } from '@automapper/types';
import {
MapFnClassId,
MappingPropertiesClassId,
MappingPropertyClassId,
MappingTransformationClassId,
} from '@automapper/types';

/**
*
Expand Down Expand Up @@ -39,21 +44,24 @@ export function applyTypeConverters(
?.get(destinationType as PrimitiveConstructorWithDate);
if (typeConverter) {
const originalMapInitializeFn =
initializeProp[MappingPropertiesClassId.property][1][0][
MapFnClassId.fn
];
initializeProp[MappingPropertiesClassId.property][
MappingPropertyClassId.transformation
][MappingTransformationClassId.memberMapFn][MapFnClassId.fn];

initializeProp[MappingPropertiesClassId.property][1][0][MapFnClassId.fn] =
(source) => {
if ('convert' in typeConverter) {
return typeConverter.convert(
(originalMapInitializeFn as ValueSelector)(source)
);
}
return typeConverter(
initializeProp[MappingPropertiesClassId.property][
MappingPropertyClassId.transformation
][MappingTransformationClassId.memberMapFn][MapFnClassId.fn] = (
source
) => {
if ('convert' in typeConverter) {
return typeConverter.convert(
(originalMapInitializeFn as ValueSelector)(source)
);
};
}
return typeConverter(
(originalMapInitializeFn as ValueSelector)(source)
);
};
}
}
}
25 changes: 18 additions & 7 deletions packages/core/src/lib/create-mapper/create-map-for-self.util.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { Mapping, Selector } from '@automapper/types';
import {
Mapping,
MapFnClassId,
MappingClassId,
MappingPropertiesClassId,
Selector,
MappingPropertyClassId,
MappingTransformationClassId,
TransformationType,
} from '@automapper/types';
import { get } from '@automapper/core';
import { get } from '../utils';

export function createMapForSelf<TSource, TDestination>(
mapping: Mapping<TSource, TDestination>,
Expand All @@ -19,11 +21,11 @@ export function createMapForSelf<TSource, TDestination>(

for (let i = 0, keysLen = sourceInstanceKeys.length; i < keysLen; i++) {
const key = sourceInstanceKeys[i];
const foundMapInitialized = mapping[MappingClassId.properties].find(
([[path]]) => path === key
const foundMapProperty = mapping[MappingClassId.properties].find(
(property) => property[MappingPropertiesClassId.path].indexOf(key) === 0
);

if (!foundMapInitialized) {
if (!foundMapProperty) {
mapping[MappingClassId.properties].push([
[key],
[
Expand All @@ -38,7 +40,16 @@ export function createMapForSelf<TSource, TDestination>(
],
]);
} else {
foundMapInitialized[MappingPropertiesClassId.property][1][0] = [
if (
foundMapProperty[MappingPropertiesClassId.property][
MappingPropertyClassId.transformation
][MappingTransformationClassId.memberMapFn][MapFnClassId.type] !==
TransformationType.MapInitialize
)
continue;
foundMapProperty[MappingPropertiesClassId.property][
MappingPropertyClassId.transformation
][MappingTransformationClassId.memberMapFn] = [
TransformationType.MapInitialize,
(originalSource) => get(selector(originalSource), [key]),
];
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/lib/create-mapper/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export * from './create-mapper';
export { createMapForMember } from './create-map-for-member.util';
export { createMapFluentFunction } from './create-map-fluent-function.util';
21 changes: 21 additions & 0 deletions packages/integration-test/src/lib/with-classes/map-self.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,25 @@ describe('Map - Self', () => {
expect(dto.quantity).toEqual(cartItem.quantity);
expect(dto.total).toEqual(cartItem.quantity * item.price);
});

it('should map correctly for forMember that overrides BEFORE forSelf', () => {
mapper.createMap(Item, CartItemDto);
mapper
.createMap(CartItem, CartItemDto)
.forMember((d) => d.name, fromValue('override before name'))
.forSelf(Item, (src) => src.item);

const item = new Item();
item.name = 'item1';
item.price = 123;
const cartItem = new CartItem();
cartItem.item = item;
cartItem.quantity = 10;

const dto = mapper.map(cartItem, CartItemDto, CartItem);
expect(dto.name).toEqual('override before name');
expect(dto.price).toEqual(item.price);
expect(dto.quantity).toEqual(cartItem.quantity);
expect(dto.total).toEqual(cartItem.quantity * item.price);
});
});
16 changes: 16 additions & 0 deletions packages/types/src/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ export const enum MappingPropertiesClassId {
nestedMappingPair,
}

export const enum MappingPropertyClassId {
targetAndOrigin,
transformation,
}

export const enum MappingPropertyTargetOriginClassId {
target,
origin,
}

export const enum MappingTransformationClassId {
memberMapFn,
metadataNullFlag,
preCond,
}

export const enum MapFnClassId {
type,
fn,
Expand Down

0 comments on commit ef7471a

Please sign in to comment.