in packages/@aws-c2a/engine/lib/model-diffing/property-diff.ts [63:138]
private fromRecordProperties(
p1: ComponentPropertyValue,
p2: ComponentPropertyValue,
pathP1: Array<string | number>,
pathP2: Array<string | number>,
): PropertyDiff {
const [p1Record, p2Record] = [p1,p2].map(p => p.getRecord());
const sameNameKeys = arrayIntersection(Object.keys(p1Record), Object.keys(p2Record));
const pickedSameNames: [string, PropertyDiff][] = sameNameKeys
.map((k): [string, PropertyDiff] => [k, this.create(p1Record[k], p2Record[k], [...pathP1, k], [...pathP2, k])])
.map(([k, pd]): [string, PropertyDiff] => [k, {
...pd,
similarity: pd.similarity + (1 - pd.similarity)*(1/(pd.weight+1)), // keys impact similiarity as much as string values
weight: pd.weight + 1,
}]);
const pickedSameNameKeys = new Set(pickedSameNames.map(([k]) => k));
const sameNameDiffs = pickedSameNames.map(([, pd]) => pd);
const renamedDiffMatchResults = matchEntities<string, PropertyDiff>(
Object.keys(p1Record).filter((k) => !pickedSameNameKeys.has(k)),
Object.keys(p2Record).filter((k) => !pickedSameNameKeys.has(k)),
propertySimilarityEvaluatorCreator(
this.componentTransition,
p1Record, p2Record, pathP1, pathP2,
),
propertySimilarityThreshold,
);
const renamedDiffs = renamedDiffMatchResults.matches.map(({transition: {v1, v2}, metadata: propDiff}) => {
if(!v1 || !v2)
throw Error('Entity matching returned undefined versions');
return {
similarity: propDiff.similarity,
weight: propDiff.weight,
operation: new MovePropertyComponentOperation({}, {
pathTransition: new Transition({v1: [...pathP1, v1[0]], v2: [...pathP2, v2[0]]}),
propertyTransition: new Transition({v1: p1Record[v1], v2: p2Record[v2]}),
componentTransition: this.componentTransition,
innerOperations: (propDiff.operation as UpdatePropertyComponentOperation)?.innerOperations,
}),
};
});
const removedDiffs = renamedDiffMatchResults.unmatchedA.map((k) => ({
similarity: 0,
weight: this.calcPropertyWeight(p1Record[k]),
operation: new RemovePropertyComponentOperation(
{},
{
pathTransition: new Transition({v1: [...pathP1, k]}),
propertyTransition: new Transition({v1: p1Record[k]}),
componentTransition: this.componentTransition,
}),
}));
const insertedDiffs = renamedDiffMatchResults.unmatchedB.map((k) => ({
similarity: 0,
weight: this.calcPropertyWeight(p2Record[k]),
operation: new InsertPropertyComponentOperation(
{},
{
pathTransition: new Transition({v2: [...pathP2, k]}),
propertyTransition: new Transition({v2: p2Record[k]}),
componentTransition: this.componentTransition,
}),
}));
return this.fromCollectionDiffs(
p1,
p2,
[...sameNameDiffs, ...renamedDiffs, ...removedDiffs, ...insertedDiffs],
pathP1,
pathP2);
}