All files / common/utils/src clone.util.ts

72.22% Statements 13/18
100% Branches 8/8
37.5% Functions 3/8
70.58% Lines 12/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 4910x 10x         10x         1x   1x 1x   1x       4x   4x     3x               1x           1x                  
import { assert } from './assert.util';
import { defineMetadata, getMetadata, getMetadataKeys } from './meta.util';
 
/**
 * @internal
 */
export const _copyPropsAndMeta = <T extends {} = any>(
  target: T,
  source: T,
  propertyKeys: (string | symbol)[] = [],
) => {
  const valueType = typeof source;
 
  assert(valueType === 'object' || valueType === 'function');
  if (valueType === 'object' || valueType === 'function') {
    // copy static props
    Object.defineProperties(
      target,
      Object.entries(Object.getOwnPropertyDescriptors(source))
        .filter(([name]) => {
          const ownDescriptor = Object.getOwnPropertyDescriptor(target, name);
 
          return !ownDescriptor || ownDescriptor.configurable;
        })
        .reduce(
          (descriptors, [name, descriptor]) => ({
            ...descriptors,
            [name]: descriptor,
          }),
          {},
        ),
    );
 
    getMetadataKeys(source)
      .map((key) => [key, getMetadata(key, source)] as [string, any])
      .forEach(([key, value]) => {
        defineMetadata(key, value, target);
      });
 
    propertyKeys.forEach((pk) => {
      getMetadataKeys(source, pk)
        .map((key) => [key, getMetadata(key, source, pk)] as [string, any])
        .forEach(([key, value]) => {
          defineMetadata(key, value, target, pk);
        });
    });
  }
};