code: function merge(o1 = {}, o2 = {}, _depth = 0) {
      let o = {};
  
      if (Object.keys(o1 || {}).length === 0) {
          return o2 && !isEmptyObject(o2) ? o2 : {};
      }
  
      for (let k of Object.keys(o1)) {
          const nestedO = !!(o2[k] && typeof o2[k] === "object" && typeof o1[k] === "object" && _depth < MAX_DEPTH);
  
          if (nestedO) {
              const r = merge(o1[k], o2[k], _depth + 1);
  
              o[k] =
                  o1[k].hasOwnProperty("length") && o2[k].hasOwnProperty("length") ? Object.keys(r).map(rk => r[rk]) : r;
          } else {
              o[k] = o2.hasOwnProperty(k) ? o2[k] : o1[k];
          }
      }
  
      return o;
  }
docs: This function merges two objects o1 and o2, where o2 properties override existent o1 properties, and
  if o2 doesn't posses some o1 property the fallback will be the o1 property.
  @param  {Object} o1 - object.
  @param  {Object} o2 - object that will override o1 properties.
  @param  {int} [_depth=0] - the depth at which we are merging the object.
  @returns {Object} object that is the result of merging o1 and o2, being o2 properties priority overriding
  existent o1 properties.
  @memberof utils