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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | 1x 1x 1x 1x 1x 1x 1x 1x 444x 329x 329x 329x 329x 329x 115x 115x 1x 1x 1x 1x 1x 663x 453x 453x 210x 210x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1189x 526x 526x 1149x 445x 445x 445x 218x 218x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 396x 396x 396x 396x 396x 178x 178x 178x 59x 59x 178x 119x 119x 178x 396x 396x 1x 1x 1x 1x 1x 24x 24x 22x 20x 20x 2x 2x 2x 2x 1x 1x 1x 1x 1x 8x 6x 6x 2x 2x 1x 1x 1x 1x 1x 162x 162x 23x 23x 162x 6x 6x 133x 133x 385x 385x 385x 385x 385x 385x 385x 385x 385x 133x 133x 1x 1x 1x 1x 1x 10x 10x 12x 12x 12x 12x 12x 12x 12x 12x 12x 10x 10x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 170x 170x 162x 162x 8x 8x 1x 1x | const JsonGo = require('../../../index.js'); const logicalValidator = require('./src/logicalValidator.js'); const getAbsolutePath = require('./src/getAbsolutePath'); /** * returns value from provided path */ const getValueFromTransformedQuery = (element, object, currentElement, priorPath) => { if (element && element.relativePath) { const result = object.get([ ...priorPath, currentElement, ...element.relativePath, ]); return result; } return object.get(element.path); }; /** * checks if either absolutePath or relativePath is present */ const doesElementHaveAbsoluteOrRelativePath = (element) => { if (element) { return (element.absolutePath || element.relativePath); } return false; }; /** * checks whether value key is present */ const doesElementHaveValue = (element) => (element && element.value !== undefined); /** * get value for each of the query elements, either from provided value key or from objects * specified path */ const getValue = (element, object, currentElement, priorPath) => { if (doesElementHaveValue(element)) { return element.value; } if (doesElementHaveAbsoluteOrRelativePath(element)) { const transformedPath = getAbsolutePath(priorPath, element); return getValueFromTransformedQuery(transformedPath, object, currentElement, priorPath); } return undefined; }; /** * check if operation is to get end of array */ const isOperationToGetEnd = (query) => query[0] && query[0].custom === 'end'; /** * check if operation is to append to array */ const isOperationToAppend = (query) => query[0] && query[0].custom === 'append'; /** * checks each element of object/array whether it matches query */ const checkLogic = ( firstPart, operator, secondPart, results, continueAfterFirstMatch, i, type, element, ) => { let newResults = results; let nextIterationDesired = true; if (logicalValidator(firstPart, operator, secondPart, element)) { const toReturn = {}; toReturn[type] = i; if (!continueAfterFirstMatch) { newResults = toReturn; nextIterationDesired = false; } else { newResults.push(toReturn); } } return { newResults, nextIterationDesired }; }; /** * custom query end */ const getEndOfArray = (tempObject, continueAfterFirstMatch) => { const arrayEnd = tempObject.length - 1; if (arrayEnd >= 0) { if (!continueAfterFirstMatch) { return { number: tempObject.length - 1 }; } return [{ number: tempObject.length - 1 }]; } return []; }; /** * custom query append */ const getElementToAppend = (tempObject, continueAfterFirstMatch) => { if (!continueAfterFirstMatch) { return { number: tempObject.length }; } return [{ number: tempObject.length }]; }; /** * performs query for arrays */ const handleArray = (query, object, tempObject, continueAfterFirstMatch, priorPath) => { let results = []; if (isOperationToGetEnd(query)) { return getEndOfArray(tempObject, continueAfterFirstMatch); } if (isOperationToAppend(query)) { return getElementToAppend(tempObject, continueAfterFirstMatch); } tempObject.every((element, i) => { const firstPart = getValue(query[0], object, { number: i }, priorPath); const operator = getValue(query[1], object, { number: i }, priorPath); const secondPart = getValue(query[2], object, { number: i }, priorPath); const { newResults, nextIterationDesired } = checkLogic( firstPart, operator, secondPart, results, continueAfterFirstMatch, i, 'number', element, ); results = newResults; return nextIterationDesired; }); return results; }; /** * performs query for objects */ const handleObject = (query, object, tempObject, continueAfterFirstMatch, priorPath) => { let results = []; Object.keys(tempObject).every((element) => { const firstPart = getValue(query[0], object, { string: element }, priorPath); const operator = getValue(query[1], object, { string: element }, priorPath); const secondPart = getValue(query[2], object, { string: element }, priorPath); const { newResults, nextIterationDesired } = checkLogic( firstPart, operator, secondPart, results, continueAfterFirstMatch, element, 'string', ); results = newResults; return nextIterationDesired; }); return results; }; /** * Query input object and return element(s) that suffice query statement * @param {Array} q - array representation of query with lenght of 1 or 3 * @param {Any} obj - entire object/array that is queried * @param {Any} tempObject - remaining (deeper) part of object/array * @param {Boolean} continueAfterFirstMatch - indicator whether multiple outputs are desired * @param {Array} priorPath - array representation of current path * (relates to prior path where to find tempObject) * @returns {Any} - either object with first element that matches query requirement, * or an array of these objects in case of continueAfterFirstMatch */ const query = (q, obj, tempObject, continueAfterFirstMatch, priorPath) => { const object = new JsonGo.Json(obj); if (Array.isArray(tempObject)) { return handleArray(q, object, tempObject, continueAfterFirstMatch, priorPath); } return handleObject(q, object, tempObject, continueAfterFirstMatch, priorPath); }; module.exports = query; |