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

100% Statements 115/115
100% Branches 26/26
100% Functions 6/6
100% Lines 115/115

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 1161x 1x 1x 1x 1x 1x 1x 1x 127x 127x 127x 127x 127x 115x 109x 109x 109x 127x 12x 12x 127x 127x 127x 1x 1x 1x 1x 1x 188x 188x 188x 188x 188x 95x 2x 2x 2x 188x 93x 93x 188x 188x 1x 1x 1x 1x 1x 127x 127x 127x 127x 127x 115x 115x 115x 115x 127x 12x 12x 121x 121x 1x 1x 1x 1x 1x 442x 127x 127x 442x 127x 127x 188x 188x 1x 1x 1x 1x 1x 113x 113x 113x 113x 113x 113x 3514x 442x 3514x 3072x 3072x 3514x 113x 93x 93x 93x 93x 107x 107x 1x 1x 1x 1x 1x 1x 1x 436x 323x 323x 113x 113x 113x 113x 113x 1x 1x  
const queriesCache = {};
const unlink = require('../../../handlers/basic/unlink.js');
const elementTransformer = require('./elementTransformer.js');
 
/**
 * Updates counter on opening bracket, if counter is 0 push to path representation
 */
const handleOpeningBracket = (char, actionVariables) => {
  let { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
 
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(part, arrayPath));
      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) => {
  const { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
 
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(actionVariables.part, arrayPath));
      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) => {
  let { counter } = actionVariables;
  let { part } = actionVariables;
  const { arrayPath } = actionVariables;
  counter += -1;
  if (counter === 0) {
    if (part) {
      arrayPath.push(elementTransformer(part, arrayPath));
      part = '';
    }
  } else {
    part += char;
  }
  return { counter, part, arrayPath };
};
 
/**
 * Handling path separators [, ], .
 */
const handleSeperators = (char, actionVariables) => {
  if (char === '[') {
    return handleOpeningBracket(char, actionVariables);
  }
  if (char === ']') {
    return handleClosingBracket(char, actionVariables);
  }
  return handleDot(char, actionVariables);
};
 
/**
 * Handle each character and returns array with one element per key of path
 */
const charactersToArray = (characters) => {
  let actionVariables = {
    arrayPath: [],
    part: '',
    counter: 0,
  };
  characters.forEach((char) => {
    if (['[', ']', '.'].indexOf(char) > -1) {
      actionVariables = handleSeperators(char, actionVariables);
    } else {
      actionVariables.part += char;
    }
  });
  if (actionVariables.part) {
    actionVariables.arrayPath.push(elementTransformer(
      actionVariables.part, actionVariables.arrayPath,
    ));
  }
  return actionVariables.arrayPath;
};
 
/**
 * Transforms string representation of path into workable array representation
 * @param {String} query - string representation of path
 * @returns {Array} - workable array representation of path
 */
const pathToArrayTransformer = (path) => {
  if (queriesCache[path]) {
    return unlink(queriesCache[path]);
  }
  const characters = path.split('');
  const arrayPath = charactersToArray(characters);
  queriesCache[path] = unlink(arrayPath);
  return arrayPath;
};
 
module.exports = pathToArrayTransformer;