All files / latest/src/helpers/pathTransformer/src pathToArrayTransformer.js

100% Statements 124/124
100% Branches 27/27
100% Functions 7/7
100% Lines 124/124

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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 1251x 1x 1x 1x 1x 1x 1x 1x 212x 212x 212x 212x 212x 197x 191x 191x 191x 212x 15x 15x 212x 212x 212x 1x 1x 1x 1x 1x 310x 310x 310x 310x 310x 166x 6x 6x 6x 310x 144x 144x 310x 310x 1x 1x 1x 1x 1x 212x 212x 212x 212x 212x 197x 197x 197x 197x 212x 15x 15x 206x 206x 1x 1x 1x 1x 1x 734x 212x 212x 734x 212x 212x 310x 310x 1x 1x 1x 1x 1x 579x 579x 579x 579x 579x 579x 9676x 734x 9676x 8942x 8942x 9676x 579x 544x 544x 544x 544x 573x 573x 1x 1x 1x 1x 1x 579x 82x 82x 82x 497x 497x 1x 1x 1x 1x 1x 1x 1x 1x 579x 579x 579x 579x 579x 1x 1x  
const elementTransformer = require('./elementTransformer.js');
 
let functionsCache = {};
 
/**
 * Updates counter on opening bracket, if counter is 0 push to path representation
 */
const handleOpeningBracket = (char, actionVariables, funcs) => {
  let { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
 
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(part, funcs));
      part = '';
    }
  } else {
    part += char;
  }
  counter += 1;
  return { counter, part, arrayPath };
};
 
/**
 * Handling dot separator, if counter is 0, push to path representation
 */
const handleDot = (char, actionVariables, funcs) => {
  const { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
 
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(actionVariables.part, funcs));
      part = '';
    }
  } else {
    part += char;
  }
  return { counter, part, arrayPath };
};
 
/**
 * Updates counter on closing bracket, if counter is 0 push to path representation
 */
const handleClosingBracket = (char, actionVariables, funcs) => {
  let { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
  counter += -1;
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(part, funcs));
      part = '';
    }
  } else {
    part += char;
  }
  return { counter, part, arrayPath };
};
 
/**
 * Handling path separators [, ], .
 */
const handleSeperators = (char, actionVariables, funcs) => {
  if (char === '[') {
    return handleOpeningBracket(char, actionVariables, funcs);
  }
  if (char === ']') {
    return handleClosingBracket(char, actionVariables, funcs);
  }
  return handleDot(char, actionVariables, funcs);
};
 
/**
 * Handle each character and returns array with one element per key of path
 */
const charactersToArray = (characters, funcs) => {
  let actionVariables = {
    arrayPath: [],
    part: '',
    counter: 0,
  };
  characters.forEach((char) => {
    if (['[', ']', '.'].indexOf(char) > -1) {
      actionVariables = handleSeperators(char, actionVariables, funcs);
    } else {
      actionVariables.part += char;
    }
  });
  if (actionVariables.part) {
    actionVariables.arrayPath.push(elementTransformer(
      actionVariables.part, funcs,
    ));
  }
  return actionVariables.arrayPath;
};
 
/**
 * remember functions in cache so that these can be used for next query (query-in-query support)
 */
const handleFunctionsCache = (funcs) => {
  if (funcs) {
    functionsCache = funcs;
    return funcs;
  }
  return functionsCache;
};
 
/**
 * Transforms string representation of path into workable array representation
 * @param {String} query - string representation of path
 * @param {Object} funcs - object with functions provided by the user that may be part of the query
 * @returns {Array} - workable array representation of path
 */
const pathToArrayTransformer = (path, funcs) => {
  const functions = handleFunctionsCache(funcs);
  const characters = path.split('');
  const arrayPath = charactersToArray(characters, functions);
  return arrayPath;
};
 
module.exports = pathToArrayTransformer;