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 | 1x 1x 1x 1x 1x 1x 1x 1x 318x 247x 247x 247x 247x 247x 71x 71x 1x 1x 1x 1x 1x 405x 327x 327x 78x 78x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 745x 340x 340x 709x 319x 319x 319x 86x 86x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 248x 248x 248x 110x 110x 110x 25x 25x 110x 85x 85x 110x 248x 248x 1x 1x 1x 1x 1x 23x 23x 22x 20x 20x 2x 2x 1x 1x 1x 1x 1x 1x 1x 8x 4x 4x 4x 4x 1x 1x 1x 1x 1x 106x 106x 23x 23x 106x 6x 6x 77x 77x 237x 237x 237x 237x 237x 237x 237x 237x 237x 77x 77x 1x 1x 1x 1x 1x 8x 8x 12x 12x 12x 12x 12x 12x 12x 12x 12x 8x 8x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 114x 114x 106x 106x 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) => { let newResults = results; let nextIterationDesired = true; if (logicalValidator(firstPart, operator, secondPart)) { 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', ); 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; |