module.exports = function promiseDeepProp(obj, path, handler) { const props = path ? path.split(".") : []; let value = obj; return promiseEach(props, prop => { if (!prop) throw error(INVALID_PATH, {path}); if (isPlainObject(value)) { if (!value.hasOwnProperty(prop)) { value = undefined; return false; // exit the loop } } else if (Array.isArray(value)) { const index = Number(prop); if (Number.isNaN(index)) throw error(INVALID_INDEX_VALUE, {path, index}); if (index < 0 || index >= value.length) throw error(INDEX_OUT_OF_RANGE, {path, index}); prop = index; } else { throw error(OBJECT_OR_ARRAY_REQUIRED, {path, prop}); } const parent = value; value = value[prop]; return promiseSync(handler(value, prop, parent), val => { value = val; }); }).then(() => value); };
// Resolves an expression (i.e. `expr` in `${expr}') of a variable // reference to a concrete value. _resolveExpr(vars, expr, options) { return promiseEach(expr.split(","), ref => { ref = ref.trim(); const info = this._parseRef(vars, ref, options); return this._resolveRef(vars, info, options); }); }
function _cloneObject(obj, path) { const des = {}; const props = Object.keys(obj); return promiseEach(props, prop => { return promiseSync(_clone(obj[prop], prop, obj, path + "." + prop), value => { des[prop] = value; }); }).then(() => des); }