crocks
Version:
A collection of well known Algebraic Datatypes for your utter enjoyment.
65 lines (50 loc) • 1.67 kB
JavaScript
/** @license ISC License (c) copyright 2018 original and current authors */
/** @author Ian Hofmann-Hicks (evil) */
var array = require('../core/array')
var curry = require('../core/curry')
var isArray = require('../core/isArray')
var isEmpty = require('../core/isEmpty')
var isInteger = require('../core/isInteger')
var isObject = require('../core/isObject')
var isString = require('../core/isString')
var object = require('../core/object')
var isValid = function (x) { return isObject(x) || isArray(x); }
var pathErr =
'setPath: Non-empty Array of non-empty Strings and/or Positive Integers required for first argument'
// setPath :: [ String | Integer ] -> a -> (Object | Array) -> (Object | Array)
function setPath(path, val, obj) {
if(!isArray(path) || isEmpty(path)) {
throw new TypeError(pathErr)
}
if(!isValid(obj)) {
throw new TypeError(
'setPath: Object or Array required for third argument'
)
}
var key = path[0]
var newVal = val
if(!(isString(key) && !isEmpty(key) || isInteger(key) && key >= 0)) {
throw new TypeError(pathErr)
}
if(path.length > 1) {
var next = !isValid(obj[key])
? isInteger(path[1]) ? [] : {}
: obj[key]
newVal = setPath(path.slice(1), val, next)
}
if(isObject(obj)) {
if(isString(key)) {
return object.set(key, newVal, obj)
}
throw new TypeError(
'setPath: Non-empty String required in path when referencing an Object'
)
}
if(isInteger(key)) {
return array.set(key, newVal, obj)
}
throw new TypeError(
'setPath: Positive Integers required in path when referencing an Array'
)
}
module.exports = curry(setPath)