import {__, applyTo, cond, curry, identity, is, keys, merge, T} from 'ramda'
import {safeSpecTransforms, isPlainObj, objectify} from './util'
/**
* A port of [Ramda's evolve()](http://ramdajs.com/docs/#evolve), but the
* transforms are _always_ applied regardless if the key/value pair exists in
* the input object or not.
*
*
* @func
* @sig {k: (a -> b)} -> {k: v} -> {k: v}
* @param {Object} transforms An object whose values may be transform functions that
* need to be wrapped in try/catch
* @param {Object} input The input object to pass through prop-level transformations
* @returns {Object} The modified input object, with any prop-level transforms
* applied to it
*/
const alwaysEvolve = curry(
(transforms, input) => {
const result = {}
const spec = safeSpecTransforms(transforms)
const object = objectify(input)
keys(spec).forEach(key => {
result[key] = cond([
[is(Function), applyTo(object[key])],
[isPlainObj, alwaysEvolve(__, object[key])],
[T, identity]
])(spec[key])
})
return merge(input, result)
}
)
export default alwaysEvolve