/** @module Object */
import { isFunc } from '@method/isFunc'
import { deepClone } from '@collection/deepClone'
import { isObj } from './isObj'
/**
* Deep clones Object obj, then returns the result of calling function mutatorCb with the clone as its argument
* @example
* const obj = {}
* const clone = applyToCloneOf(obj, (clone) => { clone.test = 'foo'; return clone })
* console.log(obj === clone) // prints false
* console.log(clone.test === 'foo') // prints true
* @function
* @param {Object} obj - object
* @param {Function} mutatorCb - a callback that accepts one argument, the cloned obj, and mutates it in some way
* @returns {Object|Array} the mutated clone
*/
export const applyToCloneOf = (
obj: Record<any, any>,
mutatorCb: (obj: Record<any, any>) => void
): Record<any, any> => {
let error: string = undefined
if (!obj) error = 'object (Argument 1) in applyToCloneOf, must be defined!'
if (!isObj(obj))
error = 'object (Argument 1) in applyToCloneOf, must be an object!'
if (!mutatorCb)
error = 'mutator (Argument 2) in applyToCloneOf, must be defined!'
if (!isFunc(mutatorCb))
error = 'mutator (Argument 2) arg in applyToCloneOf, must be a function!'
if (error) {
console.warn(error)
return obj
}
const clone = deepClone(obj)
mutatorCb(clone)
return clone
}