123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- 'use strict';
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
- exports.default = sift;
- exports.indexOf = indexOf;
- exports.compare = compare;
- /*
- *
- * Copryright 2018, Craig Condon
- * Licensed under MIT
- *
- * Filter JavaScript objects with mongodb queries
- */
- /**
- */
- function isFunction(value) {
- return typeof value === 'function';
- }
- /**
- */
- function isArray(value) {
- return Object.prototype.toString.call(value) === '[object Array]';
- }
- /**
- */
- function comparable(value) {
- if (value instanceof Date) {
- return value.getTime();
- } else if (isArray(value)) {
- return value.map(comparable);
- } else if (value && typeof value.toJSON === 'function') {
- return value.toJSON();
- } else {
- return value;
- }
- }
- function get(obj, key) {
- return isFunction(obj.get) ? obj.get(key) : obj[key];
- }
- /**
- */
- function or(validator) {
- return function (a, b) {
- if (!isArray(b) || !b.length) {
- return validator(a, b);
- }
- for (var i = 0, n = b.length; i < n; i++) {
- if (validator(a, get(b, i))) return true;
- }
- return false;
- };
- }
- /**
- */
- function and(validator) {
- return function (a, b) {
- if (!isArray(b) || !b.length) {
- return validator(a, b);
- }
- for (var i = 0, n = b.length; i < n; i++) {
- if (!validator(a, get(b, i))) return false;
- }
- return true;
- };
- }
- function validate(validator, b, k, o) {
- return validator.v(validator.a, b, k, o);
- }
- var OPERATORS = {
- /**
- */
- $eq: or(function (a, b) {
- return a(b);
- }),
- /**
- */
- $ne: and(function (a, b) {
- return !a(b);
- }),
- /**
- */
- $gt: or(function (a, b) {
- return compare(comparable(b), a) > 0;
- }),
- /**
- */
- $gte: or(function (a, b) {
- return compare(comparable(b), a) >= 0;
- }),
- /**
- */
- $lt: or(function (a, b) {
- return compare(comparable(b), a) < 0;
- }),
- /**
- */
- $lte: or(function (a, b) {
- return compare(comparable(b), a) <= 0;
- }),
- /**
- */
- $mod: or(function (a, b) {
- return b % a[0] == a[1];
- }),
- /**
- */
- $in: function $in(a, b) {
- if (b instanceof Array) {
- for (var i = b.length; i--;) {
- if (~a.indexOf(comparable(get(b, i)))) {
- return true;
- }
- }
- } else {
- var comparableB = comparable(b);
- if (comparableB === b && (typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') {
- for (var i = a.length; i--;) {
- if (String(a[i]) === String(b) && String(b) !== '[object Object]') {
- return true;
- }
- }
- }
- /*
- Handles documents that are undefined, whilst also
- having a 'null' element in the parameters to $in.
- */
- if (typeof comparableB == 'undefined') {
- for (var i = a.length; i--;) {
- if (a[i] == null) {
- return true;
- }
- }
- }
- /*
- Handles the case of {'field': {$in: [/regexp1/, /regexp2/, ...]}}
- */
- for (var i = a.length; i--;) {
- var validator = createRootValidator(get(a, i), undefined);
- var result = validate(validator, b, i, a);
- if (result && String(result) !== '[object Object]' && String(b) !== '[object Object]') {
- return true;
- }
- }
- return !!~a.indexOf(comparableB);
- }
- return false;
- },
- /**
- */
- $nin: function $nin(a, b, k, o) {
- return !OPERATORS.$in(a, b, k, o);
- },
- /**
- */
- $not: function $not(a, b, k, o) {
- return !validate(a, b, k, o);
- },
- /**
- */
- $type: function $type(a, b) {
- return b != void 0 ? b instanceof a || b.constructor == a : false;
- },
- /**
- */
- $all: function $all(a, b, k, o) {
- return OPERATORS.$and(a, b, k, o);
- },
- /**
- */
- $size: function $size(a, b) {
- return b ? a === b.length : false;
- },
- /**
- */
- $or: function $or(a, b, k, o) {
- for (var i = 0, n = a.length; i < n; i++) {
- if (validate(get(a, i), b, k, o)) return true;
- }return false;
- },
- /**
- */
- $nor: function $nor(a, b, k, o) {
- return !OPERATORS.$or(a, b, k, o);
- },
- /**
- */
- $and: function $and(a, b, k, o) {
- for (var i = 0, n = a.length; i < n; i++) {
- if (!validate(get(a, i), b, k, o)) {
- return false;
- }
- }
- return true;
- },
- /**
- */
- $regex: or(function (a, b) {
- return typeof b === 'string' && a.test(b);
- }),
- /**
- */
- $where: function $where(a, b, k, o) {
- return a.call(b, b, k, o);
- },
- /**
- */
- $elemMatch: function $elemMatch(a, b, k, o) {
- if (isArray(b)) {
- return !!~search(b, a);
- }
- return validate(a, b, k, o);
- },
- /**
- */
- $exists: function $exists(a, b, k, o) {
- return o.hasOwnProperty(k) === a;
- }
- };
- /**
- */
- var prepare = {
- /**
- */
- $eq: function $eq(a) {
- if (a instanceof RegExp) {
- return function (b) {
- return typeof b === 'string' && a.test(b);
- };
- } else if (a instanceof Function) {
- return a;
- } else if (isArray(a) && !a.length) {
- // Special case of a == []
- return function (b) {
- return isArray(b) && !b.length;
- };
- } else if (a === null) {
- return function (b) {
- //will match both null and undefined
- return b == null;
- };
- }
- return function (b) {
- return compare(comparable(b), comparable(a)) === 0;
- };
- },
- /**
- */
- $ne: function $ne(a) {
- return prepare.$eq(a);
- },
- /**
- */
- $and: function $and(a) {
- return a.map(parse);
- },
- /**
- */
- $all: function $all(a) {
- return prepare.$and(a);
- },
- /**
- */
- $or: function $or(a) {
- return a.map(parse);
- },
- /**
- */
- $nor: function $nor(a) {
- return a.map(parse);
- },
- /**
- */
- $not: function $not(a) {
- return parse(a);
- },
- /**
- */
- $regex: function $regex(a, query) {
- return new RegExp(a, query.$options);
- },
- /**
- */
- $where: function $where(a) {
- return typeof a === 'string' ? new Function('obj', 'return ' + a) : a;
- },
- /**
- */
- $elemMatch: function $elemMatch(a) {
- return parse(a);
- },
- /**
- */
- $exists: function $exists(a) {
- return !!a;
- }
- };
- /**
- */
- function search(array, validator) {
- for (var i = 0; i < array.length; i++) {
- var result = get(array, i);
- if (validate(validator, get(array, i))) {
- return i;
- }
- }
- return -1;
- }
- /**
- */
- function createValidator(a, validate) {
- return { a: a, v: validate };
- }
- /**
- */
- function nestedValidator(a, b) {
- var values = [];
- findValues(b, a.k, 0, b, values);
- if (values.length === 1) {
- var first = values[0];
- return validate(a.nv, first[0], first[1], first[2]);
- }
- // If the query contains $ne, need to test all elements ANDed together
- var inclusive = a && a.q && typeof a.q.$ne !== 'undefined';
- var allValid = inclusive;
- for (var i = 0; i < values.length; i++) {
- var result = values[i];
- var isValid = validate(a.nv, result[0], result[1], result[2]);
- if (inclusive) {
- allValid &= isValid;
- } else {
- allValid |= isValid;
- }
- }
- return allValid;
- }
- /**
- */
- function findValues(current, keypath, index, object, values) {
- if (index === keypath.length || current == void 0) {
- values.push([current, keypath[index - 1], object]);
- return;
- }
- var k = get(keypath, index);
- // ensure that if current is an array, that the current key
- // is NOT an array index. This sort of thing needs to work:
- // sift({'foo.0':42}, [{foo: [42]}]);
- if (isArray(current) && isNaN(Number(k))) {
- for (var i = 0, n = current.length; i < n; i++) {
- findValues(get(current, i), keypath, index, current, values);
- }
- } else {
- findValues(get(current, k), keypath, index + 1, current, values);
- }
- }
- /**
- */
- function createNestedValidator(keypath, a, q) {
- return { a: { k: keypath, nv: a, q: q }, v: nestedValidator };
- }
- /**
- * flatten the query
- */
- function isVanillaObject(value) {
- return value && value.constructor === Object;
- }
- function parse(query) {
- query = comparable(query);
- if (!query || !isVanillaObject(query)) {
- // cross browser support
- query = { $eq: query };
- }
- var validators = [];
- for (var key in query) {
- var a = query[key];
- if (key === '$options') {
- continue;
- }
- if (OPERATORS[key]) {
- if (prepare[key]) a = prepare[key](a, query);
- validators.push(createValidator(comparable(a), OPERATORS[key]));
- } else {
- if (key.charCodeAt(0) === 36) {
- throw new Error('Unknown operation ' + key);
- }
- validators.push(createNestedValidator(key.split('.'), parse(a), a));
- }
- }
- return validators.length === 1 ? validators[0] : createValidator(validators, OPERATORS.$and);
- }
- /**
- */
- function createRootValidator(query, getter) {
- var validator = parse(query);
- if (getter) {
- validator = {
- a: validator,
- v: function v(a, b, k, o) {
- return validate(a, getter(b), k, o);
- }
- };
- }
- return validator;
- }
- /**
- */
- function sift(query, array, getter) {
- if (isFunction(array)) {
- getter = array;
- array = void 0;
- }
- var validator = createRootValidator(query, getter);
- function filter(b, k, o) {
- return validate(validator, b, k, o);
- }
- if (array) {
- return array.filter(filter);
- }
- return filter;
- }
- /**
- */
- function indexOf(query, array, getter) {
- return search(array, createRootValidator(query, getter));
- };
- /**
- */
- function compare(a, b) {
- if (a === b) return 0;
- if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === (typeof b === 'undefined' ? 'undefined' : _typeof(b))) {
- if (a > b) {
- return 1;
- }
- if (a < b) {
- return -1;
- }
- }
- };
|