All files / src/helpers clone-object.ts

100% Statements 6/6
83.33% Branches 5/6
100% Functions 1/1
100% Lines 6/6

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                        1x     444x 4x 4x   2x             442x    
/**
 * Returns new object with values cloned from the original object. Some objects
 * (like Sequelize or MongoDB model instances) contain circular references
 * and cause TypeError when trying to JSON.stringify() them. They may contain
 * custom toJSON() or toObject() method which allows to serialize them safely.
 * Object.assign() does not clone these methods, so the purpose of this method
 * is to use result of custom toJSON() or toObject() (if accessible)
 * for Object.assign(), but only in case of serialization failure.
 *
 * @param  obj - Object to clone
 * @returns Cloned object
 */
export default function cloneObject<T extends Record<string, unknown>> (
  obj: T
): T {
  if (typeof obj.toJSON === 'function' || typeof obj.toObject === 'function') {
    try {
      JSON.stringify(Object.assign({}, obj));
    } catch (err) {
      return (typeof obj.toJSON === 'function')
        ? obj.toJSON()
        // @ts-expect-error does not know about toObject()
        : obj.toObject();
    }
  }
 
  return Object.assign({}, obj);
}