All files / latest/src/handlers/get get.js

100% Statements 79/79
100% Branches 19/19
100% Functions 3/3
100% Lines 79/79

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 7x 7x 7x 6x 7x 1x 1x 7x 5x 5x 5x 2x 2x 5x 5x 1x 1x 1x 1x 1x 232x 5x 5x 227x 227x 1x 1x 1x 1x 1x 1x 1x 1x 1x 484x 484x 409x 409x 71x 71x 71x 232x 89x 89x 89x 89x 224x 143x 143x 143x 143x 143x 231x 231x 231x 231x 231x 231x 71x 71x 1x 1x  
const JsonGo = require('../../../index');
const pathTransformer = require('../../helpers/pathTransformer');
const getSinglePathElement = require('../../helpers/pathElements/getSingle');
const doesPathIndicateComplexity = require('./src/doesPathIndicateComplexity');
const simpleGet = require('./src/simpleGet');
const validateOutput = require('./src/validateOutput');
const getAllKeysFromObject = require('../../helpers/pathElements/getKeys/getAllKeysFromObject');
const getAllKeysFromArray = require('../../helpers/pathElements/getKeys/getAllKeysFromArray');
 
/**
 * Handle wildcard, checks for each key whether remaining path is found and returns first key that
 * matches
 */
const getFirstKey = (tempObject, arrayPath, getType, index, obj, priorPath) => {
  const keys = getType === 'number' ? getAllKeysFromArray(tempObject) : getAllKeysFromObject(tempObject);
  let result;
  keys.some((key) => {
    let iterationResult;
    const remainingPath = arrayPath.slice(index + 1);
    if (doesPathIndicateComplexity(remainingPath)) {
      iterationResult = new JsonGo.Json(obj).get([...priorPath, key, ...remainingPath]);
    } else {
      iterationResult = simpleGet(tempObject, [key, ...remainingPath]);
    }
    if (iterationResult !== undefined) {
      result = key[getType];
      return true;
    }
    return false;
  });
  return result;
};
 
/**
 * Get name of element either from wildcard or from other type of element
 */
const getPathElement = (element, obj, tempObject, getType, priorPath, arrayPath, index) => {
  if (element.wildcard) {
    return getFirstKey(tempObject, arrayPath, getType, index, obj, priorPath);
  }
  return getSinglePathElement(element, obj, tempObject, getType, priorPath);
};
 
/**
 * Retreives single value from objects specified path
 * @param {Object} obj - object/array from which value should be retreived.
 * @param {any} path - string or array representation of path to set.
 * @returns {any} returns value found at specified path, in case that multiple logical checks
 * satisfy the first element will be returned
 */
const get = (obj, path, functions) => {
  const arrayPath = pathTransformer(path, functions);
  if (!doesPathIndicateComplexity(arrayPath)) {
    return simpleGet(obj, arrayPath);
  }
  const priorPath = [];
  let tempObject = obj;
  arrayPath.every((element, index) => {
    if (Array.isArray(tempObject)) {
      const elementValue = getPathElement(element, obj, tempObject, 'number', priorPath, arrayPath, index);
      tempObject = tempObject[elementValue];
      arrayPath[index] = elementValue;
      priorPath.push({ number: elementValue });
    } else {
      const elementValue = getPathElement(element, obj, tempObject, 'string', priorPath, arrayPath, index);
      tempObject = tempObject[elementValue];
      arrayPath[index] = elementValue;
      priorPath.push({ string: elementValue });
    }
    const {
      shouldItContinue, newTempObject,
    } = validateOutput(tempObject, arrayPath.length - 1 === index);
    tempObject = newTempObject;
    return shouldItContinue;
  });
  return tempObject;
};
 
module.exports = get;