UNPKG

@irrelon/forerunnerdb-core

Version:

ForerunnerDB core utilities for operating on JSON data.

295 lines (287 loc) 10.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.operationLookup = exports.matchPipeline = exports.gates = exports.$or = exports.$not = exports.$nin = exports.$nee = exports.$ne = exports.$lte = exports.$lt = exports.$in = exports.$gte = exports.$gt = exports.$fastNin = exports.$fastIn = exports.$exists = exports.$eq = exports.$eeq = exports.$distinct = exports.$count = exports.$and = void 0; var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _path = require("@irrelon/path"); var _this = void 0; var gates = exports.gates = ["$and", "$or", "$not", "$nor"]; var matchPipeline = exports.matchPipeline = function matchPipeline(pipeline, data) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": {} }; var opFunc = operationLookup[pipeline.op]; if (!opFunc) { throw new Error("Unknown operation \"".concat(pipeline.op, "\"")); } return opFunc(data, pipeline.value, { "originalQuery": extraInfo.originalQuery, "operation": pipeline }); }; var $and = exports.$and = function $and(dataItem, opArr) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": {} }; // Match true on ALL operations to pass, if any are // returned then we have found a NON MATCHING entity return opArr.every(function (opData) { var dataValue; var opValue; var opFunc; if (gates.indexOf(opData.op) > -1) { // The operation is a gate return operationLookup[opData.op](dataItem, opData.value, extraInfo); } dataValue = (0, _path.get)(dataItem, opData.path, undefined, { "arrayTraversal": true, "arrayExpansion": true }); opFunc = operationLookup[opData.op]; opValue = opData.value; if (!opFunc) { throw new Error("Unknown operation \"".concat(opData.op, "\" in operation ").concat(JSON.stringify(opData))); } return opFunc(dataValue, opValue, { "originalQuery": extraInfo.originalQuery, "operation": opData }); }); }; var $not = exports.$not = function $not(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": {} }; // Not operator return !$and(data, query, extraInfo); }; var $or = exports.$or = function $or(dataItem, opArr) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": {} }; // Match true on ANY operations to pass, if any are // returned then we have found a NON MATCHING entity return opArr.some(function (opData) { var dataValue; var opValue; var opFunc; if (gates.indexOf(opData.op) > -1) { // The operation is a gate return operationLookup[opData.op](dataItem, opData.value, extraInfo); } dataValue = (0, _path.get)(dataItem, opData.path, undefined, { "arrayTraversal": true }); opFunc = operationLookup[opData.op]; opValue = opData.value; if (!opFunc) { throw new Error("Unknown operation \"".concat(opData.op, "\"")); } return opFunc(dataValue, opValue, { "originalQuery": extraInfo.originalQuery, "operation": opData }); }); }; var normalise = function normalise(data) { if (data instanceof Date) { return data.toISOString(); } return data; }; var $gt = exports.$gt = function $gt(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Greater than return normalise(data) > normalise(query); }; var $gte = exports.$gte = function $gte(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Greater than or equal return normalise(data) >= normalise(query); }; var $lt = exports.$lt = function $lt(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Less than return normalise(data) < normalise(query); }; var $lte = exports.$lte = function $lte(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Less than or equal return normalise(data) <= normalise(query); }; var $exists = exports.$exists = function $exists(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Property exists return data === undefined !== normalise(query); }; var $eq = exports.$eq = function $eq(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Equals // eslint-disable-next-line eqeqeq return normalise(data) == normalise(query); // jshint ignore:line }; var $eeq = exports.$eeq = function $eeq(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Equals equals return normalise(data) === normalise(query); }; var $ne = exports.$ne = function $ne(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Not equals // eslint-disable-next-line eqeqeq return normalise(data) != normalise(query); // eslint ignore:line }; // Not equals equals var $nee = exports.$nee = function $nee(data, query) { var extraInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return normalise(data) !== normalise(query); }; var $in = exports.$in = function $in(data, query) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": undefined, "operation": undefined }, originalQuery = _ref.originalQuery, operation = _ref.operation; // Check that the in query is an array if (Array.isArray(query)) { var inArr = query, inArrCount = inArr.length, inArrIndex; for (inArrIndex = 0; inArrIndex < inArrCount; inArrIndex++) { if ($eeq(data, inArr[inArrIndex], { originalQuery: originalQuery, operation: operation })) { return true; } } return false; } console.log("Cannot use an $in operator on non-array data in query ".concat(JSON.stringify(originalQuery))); return false; }; var $nin = exports.$nin = function $nin(data, query) { var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": undefined, "operation": undefined }, originalQuery = _ref2.originalQuery, operation = _ref2.operation; // Check that the in query is an array if (Array.isArray(query)) { var inArr = query, inArrCount = inArr.length, inArrIndex; for (inArrIndex = 0; inArrIndex < inArrCount; inArrIndex++) { if ($eeq(data, inArr[inArrIndex], { originalQuery: originalQuery, operation: operation })) { return false; } } return true; } console.log("Cannot use an $in operator on non-array data in query ".concat(JSON.stringify(originalQuery))); return false; }; var $fastIn = exports.$fastIn = function $fastIn(data, query) { var _ref3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": undefined, "operation": undefined }, originalQuery = _ref3.originalQuery, operation = _ref3.operation; if (query instanceof Array) { // Data is a string or number, use indexOf to identify match in array return query.indexOf(data) !== -1; } console.log("Cannot use an $in operator on non-array data in query ".concat(JSON.stringify(originalQuery))); return false; }; var $fastNin = exports.$fastNin = function $fastNin(data, query) { var _ref4 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { "originalQuery": undefined, "operation": undefined }, originalQuery = _ref4.originalQuery, operation = _ref4.operation; if (query instanceof Array) { // Data is a string or number, use indexOf to identify match in array return query.indexOf(data) === -1; } console.log("Cannot use an $in operator on non-array data in query ".concat(JSON.stringify(originalQuery))); return false; }; var $distinct = exports.$distinct = function $distinct(data, query) { var lookupPath, value, finalDistinctProp; // Ensure options holds a distinct lookup options.$rootData["//distinctLookup"] = options.$rootData["//distinctLookup"] || {}; for (var distinctProp in query) { if (query.hasOwnProperty(distinctProp)) { if ((0, _typeof2["default"])(query[distinctProp]) === "object") { // Get the path string from the object lookupPath = _this.sharedPathSolver.parse(query)[0].path; // Use the path string to find the lookup value from the data data value = _this.sharedPathSolver.get(data, lookupPath); finalDistinctProp = lookupPath; } else { value = data[distinctProp]; finalDistinctProp = distinctProp; } options.$rootData["//distinctLookup"][finalDistinctProp] = options.$rootData["//distinctLookup"][finalDistinctProp] || {}; // Check if the options distinct lookup has this field's value if (options.$rootData["//distinctLookup"][finalDistinctProp][value]) { // Value is already in use return false; } else { // Set the value in the lookup options.$rootData["//distinctLookup"][finalDistinctProp][value] = true; // Allow the item in the results return true; } } } }; var $count = exports.$count = function $count(data, query) { var countKey, countArr, countVal; // Iterate the count object's keys for (countKey in query) { if (Object.hasOwnProperty.call(query, countKey)) { // Check the property exists and is an array. If the property being counted is not // an array (or doesn't exist) then use a value of zero in any further count logic countArr = data[countKey]; if ((0, _typeof2["default"])(countArr) === "object" && countArr instanceof Array) { countVal = countArr.length; } else { countVal = 0; } // Now recurse down the query chain further to satisfy the query for this key (countKey) if (!_this._match(countVal, query[countKey], queryOptions, "and", options)) { return false; } } } // Allow the item in the results return true; }; var operationLookup = exports.operationLookup = { $eq: $eq, $eeq: $eeq, $ne: $ne, $nee: $nee, $gt: $gt, $gte: $gte, $lt: $lt, $lte: $lte, $and: $and, $or: $or, $in: $in, $nin: $nin, $fastIn: $fastIn, $fastNin: $fastNin, $exists: $exists };