Skip to content

Commit

Permalink
fix(core): consolidate some logic between forMember and createInitial…
Browse files Browse the repository at this point in the history
…Mapping
  • Loading branch information
nartc committed Mar 10, 2023
1 parent 49d95e5 commit 88397b4
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 69 deletions.
49 changes: 14 additions & 35 deletions packages/core/src/lib/mapping-configurations/for-member.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { createMappingUtil } from '../mappings/create-initial-mapping';
import { createMap } from '../mappings/create-map';
import { getMetadataMap } from '../symbols';
import type {
Dictionary,
Expand Down Expand Up @@ -53,61 +55,38 @@ export function forMember<
];

return (mapping) => {
// TODO: consolidate this logic with the one in createInitialMapping
const [sourceIdentifier, destinationIdentifier] =
mapping[MappingClassId.identifiers];
const mapper = mapping[MappingClassId.mapper];
const namingConventions = mapping[MappingClassId.namingConventions];
const [sourceObject] = mapping[MappingClassId.identifierMetadata];

const metadataMap = getMetadataMap(mapper);
const destinationMetadata =
metadataMap.get(destinationIdentifier) || [];
const sourceMetadata = metadataMap.get(sourceIdentifier) || [];
const { getNestedMappingPair, getMetadataAtMember, processSourcePath } =
createMappingUtil(mapper, sourceIdentifier, destinationIdentifier);

let nestedMappingPair: NestedMappingPair | undefined = undefined;

const metadataAtMember = destinationMetadata.find((metadata) =>
isPrimitiveArrayEqual(
metadata[MetadataClassId.propertyKeys],
memberPath
)
const sourcePath = processSourcePath(
sourceObject,
namingConventions,
memberPath
);

let sourcePath = memberPath;

if (namingConventions) {
sourcePath = getFlatteningPaths(
sourceObject,
getPath(memberPath, namingConventions),
namingConventions
);
}

// sourcePath is not in sourceObject. No AutoMap available
if (!(sourcePath[0] in sourceObject)) {
mapping[MappingClassId.customProperties].push([
memberPath,
mappingProperty,
nestedMappingPair,
undefined,
]);
return;
}

const metadataAtSource = sourceMetadata.find((metadata) =>
isPrimitiveArrayEqual(
metadata[MetadataClassId.propertyKeys],
sourcePath
)
const metadataAtMember = getMetadataAtMember(memberPath, 'destination');
const metadataAtSource = getMetadataAtMember(sourcePath, 'source');
const nestedMappingPair = getNestedMappingPair(
metadataAtSource,
metadataAtMember
);

if (metadataAtSource && metadataAtMember) {
nestedMappingPair = [
metadataAtMember[MetadataClassId.metaFn](),
metadataAtSource[MetadataClassId.metaFn](),
];
}

mapping[MappingClassId.customProperties].push([
memberPath,
mappingProperty,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { fromValue } from '../../member-map-functions/from-value';
import type { Mapping } from '../../types';
import type { Mapping, Mapper } from '../../types';
import { MappingClassId } from '../../types';
import { forMember } from '../for-member';

describe(forMember.name, () => {
// TODO: revisit this test as forMember is more complex now
it.skip('should update mapping properties with member map fn', () => {
const mapping = [] as unknown as Mapping;
mapping[MappingClassId.mapper] = {} as Mapper;
mapping[MappingClassId.properties] = [];

const memberMapFn = fromValue('foo');
Expand Down
104 changes: 72 additions & 32 deletions packages/core/src/lib/mappings/create-initial-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
Mapping,
MappingConfiguration,
MappingTransformation,
Metadata,
MetadataIdentifier,
NestedMappingPair,
Selector,
Expand Down Expand Up @@ -94,10 +95,8 @@ export function createInitialMapping<
const hasCustomMappingProperties = customMappingProperties.length > 0;

const namingConventions = mapping[MappingClassId.namingConventions];

const metadataMap = getMetadataMap(mapper);
const destinationMetadata = metadataMap.get(destination) || [];
const sourceMetadata = metadataMap.get(source) || [];
const { processSourcePath, getMetadataAtMember, getNestedMappingPair } =
createMappingUtil(mapper, source, destination);

for (let i = 0, length = destinationPaths.length; i < length; i++) {
const destinationPath = destinationPaths[i];
Expand All @@ -116,50 +115,35 @@ export function createInitialMapping<
continue;
}

const metadataAtDestination = destinationMetadata.find((metadata) =>
isPrimitiveArrayEqual(
metadata[MetadataClassId.propertyKeys],
destinationPath
)
);

// try getting the sourcePath that is associated with this destinationPath
/**
* with naming conventions: fooBar -> [foo, bar]
* without naming conventions: fooBar -> fooBar
*/
let sourcePath = destinationPath;

if (namingConventions) {
sourcePath = getFlatteningPaths(
sourceObject,
getPath(destinationPath, namingConventions),
namingConventions
);
}
const sourcePath = processSourcePath(
sourceObject as TSource,
namingConventions,
destinationPath
);

// sourcePath is not in sourceObject. No AutoMap available
if (!(sourcePath[0] in sourceObject)) {
continue;
}

const metadataAtSource = sourceMetadata.find((metadata) =>
isPrimitiveArrayEqual(
metadata[MetadataClassId.propertyKeys],
sourcePath
)
const metadataAtDestination = getMetadataAtMember(
destinationPath,
'destination'
);

let nestedMappingPair: NestedMappingPair | undefined = undefined;
const metadataAtSource = getMetadataAtMember(sourcePath, 'source');

if (!metadataAtSource && !metadataAtDestination) continue;

if (metadataAtSource && metadataAtDestination) {
nestedMappingPair = [
metadataAtDestination[MetadataClassId.metaFn](),
metadataAtSource[MetadataClassId.metaFn](),
];
}
const nestedMappingPair = getNestedMappingPair(
metadataAtSource,
metadataAtDestination
);

const transformation: MappingTransformation<TSource, TDestination> = [
mapInitialize(sourcePath),
Expand Down Expand Up @@ -229,3 +213,59 @@ export function createInitialMapping<

return mapping;
}

export function createMappingUtil<
TSource extends Dictionary<TSource>,
TDestination extends Dictionary<TDestination>
>(
mapper: Mapper,
sourceIdentifier: MetadataIdentifier<TSource>,
destinationIdentifier: MetadataIdentifier<TDestination>
) {
const metadataMap = getMetadataMap(mapper);
const destinationMetadata = metadataMap.get(destinationIdentifier) || [];
const sourceMetadata = metadataMap.get(sourceIdentifier) || [];

return {
getMetadataAtMember: (
memberPath: string[],
type: 'source' | 'destination'
) =>
(type === 'source' ? sourceMetadata : destinationMetadata).find(
(m) =>
isPrimitiveArrayEqual(
m[MetadataClassId.propertyKeys],
memberPath
)
),
processSourcePath: (
sourceObject: TSource,
namingConventions: Mapping[MappingClassId.namingConventions],
memberPath: string[]
) => {
let sourcePath = memberPath;

if (namingConventions) {
sourcePath = getFlatteningPaths(
sourceObject,
getPath(memberPath, namingConventions),
namingConventions
);
}

return sourcePath;
},
getNestedMappingPair: (
metadataAtSource: Metadata | undefined,
metadataAtDestination: Metadata | undefined
): NestedMappingPair | undefined => {
if (metadataAtSource && metadataAtDestination) {
return [
metadataAtDestination[MetadataClassId.metaFn](),
metadataAtSource[MetadataClassId.metaFn](),
];
}
return undefined;
},
};
}

0 comments on commit 88397b4

Please sign in to comment.