private fromRecordProperties()

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);
  }