Comparing version 1.3.2 to 1.3.3
Changelog | ||
========= | ||
## 1.3.3 / 2017-08-02 | ||
- Fix `computeValue` not overriding group operator keys after resolving expression | ||
- Added `$in`, `$objectToArray`, and `$arrayToObject` array aggregation operators | ||
- Minor refactoring | ||
## 1.3.2 / 2017-07-28 | ||
@@ -4,0 +9,0 @@ - Restore `setup` function. https://github.com/kofrasa/mingo/issues/56 |
@@ -1,7 +0,7 @@ | ||
// mingo.js 1.3.2 | ||
// mingo.js 1.3.3 | ||
// Copyright (c) 2017 Francis Asante | ||
// https://github.com/kofrasa/mingo | ||
// MIT | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.mingo=t()}(this,function(){"use strict";function n(n,t){m(n)&&O(t)}function t(n){switch(r(n)){case"array":return n.map(t);case"object":return A(n,t);default:return n}}function e(n){return null===n?"Null":void 0===n?"Undefined":n.constructor.name}function r(n){return e(n).toLowerCase()}function u(n){return"boolean"===r(n)}function o(n){return"string"===r(n)}function i(n){return"number"===r(n)}function a(n){return"array"===r(n)}function l(n){return"object"===r(n)}function s(n){return n===Object(n)}function c(n){return"date"===r(n)}function f(n){return"regexp"===r(n)}function v(n){return"function"===r(n)}function h(n){return p(n)||d(n)}function p(n){return"null"===r(n)}function d(n){return"undefined"===r(n)}function g(n,t){return n.includes(t)}function $(n,t){return!n.includes(t)}function y(n){return!!n}function m(n){return!n}function b(n){return h(n)||a(n)&&0===n.length||l(n)&&0===w(n).length||!n}function _(n){return a(n)?n:[n]}function x(n,t){return Object.prototype.hasOwnProperty.call(n,t)}function O(n){throw new Error(n)}function w(n){return Object.keys(n)}function j(n,t){n.__mingo__=Object.assign(n.__mingo__||{},t)}function k(n,t){return x(n,"__mingo__")&&l(t)&&S(Object.assign({},n.__mingo__,t),n.__mingo__)}function N(n){x(n,"__mingo__")&&delete n.__mingo__}function M(t,e){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;n(t===Object(t),"Cannot iterate over object of type '"+r(t)+"'");var o=!1,i=function(){o=!0,O("halt")};if(a(t))for(var l=0,s=t.length;l<s;l++)try{e.call(u,t[l],l,t,i)}catch(t){return void n(o,t.message)}else for(var c in t)if(x(t,c))try{e.call(u,t[c],c,t,i)}catch(t){return void n(o,t.message)}}function A(n,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(a(n))return n.map(t,e);if(l(n)){for(var r,u={},o=w(n),i=0,s=o.length;i<s;i++)r=o[i],u[r]=t.call(e,n[r],r);return u}O("Input must be an Array or Object type")}function E(n,t){return n.filter(g.bind(null,t))}function I(n,t){var e=[];return R(e,n),R(e,t.filter($.bind(null,n))),e}function S(n,t){if(n===t)return!0;var e=r(n);if(e!==r(t)||"function"===e)return!1;if("number"===e&&isNaN(n)&&isNaN(t))return!0;if(g(["date","regexp"],e))return n.toString()===t.toString();if("array"===e){if(n.length===t.length&&0===n.length)return!0;if(n.length!==t.length)return!1;for(var u=0,o=n.length;u<o;u++)if(!S(n[u],t[u]))return!1}else{if(![n,t].every(l))return C(n)===C(t);var i=w(n),a=w(t);if(i.length!==a.length)return!1;if(i.sort(),a.sort(),!S(i,a))return!1;for(var s=0,c=i.length;s<c;s++){var f=i[s];if(!S(n[f],t[f]))return!1}}return!0}function q(n){var t={},e=[];return M(n,function(n){var r=C(n);x(t,r)||(e.push(n),t[r]=0)}),e}function P(n){return(Math.E+Math.random()).toString(36).slice(2,n+2)}function T(n){var t=r(n);switch(t){case"function":return P(7);case"boolean":case"number":case"regex":return n.toString();case"string":return JSON.stringify(n);case"date":return n.toISOString();case"null":case"undefined":return t;case"array":return"["+A(n,function(n){return""+T(n)})+"]";default:var u=l(n)?"":e(n)+"|",o=w(n);return o.sort(),u+"{"+A(o,function(t){return T(t)+":"+T(n[t])})+"}"}}function C(n){var t=0,e=void 0,r=void 0,u=void 0,o=T(n);if(0===o.length)return t;for(e=0,u=o.length;e<u;e++)r=o.charCodeAt(e),t=(t<<5)-t+r,t|=0;return t.toString()}function D(t,e){for(var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,u={},o=[],i=t.length,a=[],l=0;l<i;l++){var s=t[l],c=e.call(r,s,l);if(h(c))a.push(s);else{var f=C(s);x(u,f)||(u[f]=[c,l]),o.push(s)}}return o.sort(function(n,t){var e=u[C(n)],r=u[C(t)];return e[0]<r[0]?-1:e[0]>r[0]?1:e[1]<r[1]?-1:e[1]>r[1]?1:0}),R(a,o),n(a.length===t.length,"sortBy must retain collection length"),a}function F(t,e,r){var u={keys:[],groups:[]},o={};return M(t,function(n){var t=e.call(r,n),i=C(t),a=-1;d(o[i])&&(a=u.keys.length,o[i]=a,u.keys.push(t),u.groups.push([])),a=o[i],u.groups[a].push(n)}),n(u.keys.length===u.groups.length,"Cardinality must be equal for groups and keys"),u}function R(n,t){Array.prototype.push.apply(n,t)}function U(n,t){for(var e=0,r=n.length-1;e<=r;){var u=Math.round(e+(r-e)/2);if(t<n[u])r=u-1;else{if(!(t>n[u]))return u;e=u+1}}return e}function L(n){var t=this;return function(e){return function(){for(var r=arguments.length,u=Array(r),o=0;o<r;o++)u[o]=arguments[o];var i=C(u);return x(e,i)||(e[i]=n.apply(t,u)),e[i]}}({})}function B(t,e,r){if(g(H(Cn),e))return fn[e](t,r);if(l(r)){var u={};return M(r,function(e,o,i,a){u[o]=B(t,o,r[o]),g(H(Cn),o)&&(u=u[o],n(1===w(r).length,"Invalid $group expression '"+JSON.stringify(r)+"'"),a())}),u}}function Y(t,e){return n(a(e),"Aggregation pipeline must be an array"),new $n(e).run(t)}function J(n,t,e){return new _n(t).find(n,e)}function z(n,t){return new _n(t).remove(n)}function G(n,t){return new Array(Math.max(t-String(n).length+1,0)).join("0")+n}function H(n){return w(Pn[n])}function Q(t,e){var r=e(sn());n(x(Pn,t),"Could not identify operator class '"+t+"'");var o=Pn[t];M(r,function(e,r){n(/^\$\w+$/.test(r),"Invalid operator name '"+r+"'"),n(!x(o,r),"Operator "+r+" is already defined for "+t+" operators")});var i={};switch(t){case Rn:M(r,function(n,t){i[t]=function(n,e){return function(r,o){return{test:function(i){var a=X(i,r),l=n.call(e,r,a,o);return u(l)?l:l instanceof _n?l.test(i):void O("Invalid return type for '"+t+"'. Must return a Boolean or Query")}}}}(n,r)});break;case Fn:M(r,function(n,t){i[t]=function(n,t){return function(e,r,u){var o=X(e,u);return n.call(t,u,o,r)}}(n,r)});break;default:M(r,function(n,t){i[t]=function(n,t){return function(){for(var e=arguments.length,r=Array(e),u=0;u<e;u++)r[u]=arguments[u];return n.apply(t,r)}}(n,r)})}Object.assign(Pn[t],i)}function V(n){Object.assign(Un,n||{})}function K(){return Un.key}function W(n,t){return n[t]}function X(n,t){var e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=t.split("."),u=n;n:for(var o=0;o<r.length;o++){var i=function(n){if(null===r[n].match(/^\d+$/)&&a(u)){if(!0===e&&0===n)return{v:u};u=u.map(function(t){return X(t,r[n],!0)}),j(u,{isMulti:!0}),1===u.length&&(u=u[0])}else u=W(u,r[n]),e=!1;if(h(u))return"break"}(o);switch(i){case"break":break n;default:if("object"===(void 0===i?"undefined":pn(i)))return i.v}}return u}function Z(t,e){if(!h(t)){var r=e.split("."),u=r[0],o=1===r.length||r.slice(1).join("."),i=null!==u.match(/^\d+$/),l=r.length>1,s=void 0,c=void 0;try{a(t)?i?(s=W(t,u),l&&(s=Z(s,o)),n(!d(s)),s=[s]):(s=[],M(t,function(n){c=Z(n,e),h(c)||s.push(c)}),n(s.length>0)):(c=W(t,u),l&&(c=Z(c,o)),n(!d(c)),s={},s[u]=c)}catch(n){s=void 0}return s}}function nn(n,t,e){var r=arguments.length>3&&void 0!==arguments[3]&&arguments[3],u=t.split("."),o=u[0],i=1===u.length||u.slice(1).join(".");if(1===u.length)e(n,o);else if(a(n)&&!/^\d+$/.test(o))M(n,function(n){nn(n,t,e,r)});else{if(!0===r){var l=x(n,o);l&&!h(n[o])||(n[o]={})}nn(n[o],i,e,r)}}function tn(n,t,e){nn(n,t,function(n,t){n[t]=e},!0)}function en(n,t){nn(n,t,function(n,t){a(n)&&/^\d+$/.test(t)?n.splice(parseInt(t),1):l(n)&&delete n[t]})}function rn(n){if(g(cn,r(n)))return f(n)?{$regex:n}:{$eq:n};if(s(n)){var t=w(n);if(0===E(H(Rn),t).length)return{$eq:n};if(g(t,"$regex")){var e=n.$regex,u=n.$options||"",i="";o(e)&&(i+=e.ignoreCase||u.indexOf("i")>=0?"i":"",i+=e.multiline||u.indexOf("m")>=0?"m":"",i+=e.global||u.indexOf("g")>=0?"g":"",e=new RegExp(e,i)),n.$regex=e,delete n.$options}}return n}function un(t,e,u){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(i=i||{},i.root=i.root||t,g(H(Tn),u))return qn[u](t,e,i);if(g(H(Cn),u))return t=un(t,e,null,i),n(a(t),u+" expression must resolve to an array"),fn[u](t,null,i);if(o(e)&&e.length>0&&"$"===e[0]){if(g(Yn,e))return Ln[e](t,null,i);if(g(Jn,e))return e;var l=Yn.filter(function(n){return 0===e.indexOf(n+".")});return 1===l.length&&(l=l[0],"$$ROOT"===l&&(t=i.root),e=e.substr(l.length)),X(t,e.slice(1))}switch(r(e)){case"array":return e.map(function(n){return un(t,n,null)});case"object":var s={};return M(e,function(r,u,o,a){s[u]=un(t,r,u,i),g(H(Tn),u)&&(n(1===w(e).length,"Invalid aggregation expression '"+JSON.stringify(e)+"'"),s=s[u],a())}),s;default:return e}}function on(t,e){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return h(r)?e<0?(e=Math.max(0,t.length+e),r=t.length-e+1):(r=e,e=0):(e<0&&(e=Math.max(0,t.length+e)),n(r>0,"Invalid argument value for $slice operator. Limit must be a positive number"),r+=e),Array.prototype.slice.apply(t,[e,r])}function an(n){var t=n.data.reduce(function(n,t){return n+t},0),e=n.data.length||1,r=!0===n.sampled?1:0,u=t/(e-r);return Math.sqrt(n.data.reduce(function(n,t){return n+Math.pow(t-u,2)},0)/e)}function ln(n,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};e=e||{},e.root=e.root||n;var r=un(n,t,null,e);return g(Jn,r)?Bn[r](n,t,e):r}function sn(){return{computeValue:un,idKey:K,ops:H,resolve:X,assert:n,clone:t,each:M,err:O,getType:e,has:x,isArray:a,isBoolean:u,isDate:c,isEmpty:b,isEqual:S,isFunction:v,isNil:h,isNull:p,isNumber:i,isObject:l,isRegExp:f,isString:o,isUndefined:d,keys:w}}Function.prototype.bind||(Function.prototype.bind=function(n){if("function"!=typeof this)throw new Error("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),e=this,r=function(){},u=function(){return e.apply(this instanceof r?this:n,t.concat(Array.prototype.slice.call(arguments)))};return this.prototype&&(r.prototype=this.prototype),u.prototype=new r,u}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),e=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var r=arguments[1],u=0;u<e;){var o=t[u];if(n.call(r,o,u,t))return o;u++}}}),Array.prototype.findIndex||Object.defineProperty(Array.prototype,"findIndex",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),e=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var r=arguments[1],u=0;u<e;){var o=t[u];if(n.call(r,o,u,t))return u;u++}return-1}}),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(n,t){if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),r=e.length>>>0;if(0===r)return!1;for(var u=0|t,o=Math.max(u>=0?u:r-Math.abs(u),0);o<r;){if(function(n,t){return n===t||"number"==typeof n&&"number"==typeof t&&isNaN(n)&&isNaN(t)}(e[o],n))return!0;o++}return!1}}),"function"!=typeof Object.assign&&(Object.assign=function(n,t){if(null==n)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(n),r=Array.prototype.slice.call(arguments),u=1;u<r.length;u++){var o=r[u];if(null!=o)for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(e[i]=o[i])}return e}),Object.keys||(Object.keys=function(n){if(n!==Object(n))throw new TypeError("Object.keys called on a non-object");var t=[];for(var e in n)Object.prototype.hasOwnProperty.call(n,e)&&t.push(e);return t}),Object.values||(Object.values=function(n){if(n!==Object(n))throw new TypeError("Object.values called on a non-object");var t=[];for(var e in n)Object.prototype.hasOwnProperty.call(n,e)&&t.push(n[e]);return t});var cn=["null","undefined","boolean","number","string","date","regexp"],fn={$addToSet:function(n,t){return q(this.$push(n,t))},$sum:function(n,t){return a(n)?i(t)?n.length*t:this.$push(n,t).filter(i).reduce(function(n,t){return n+t},0):0},$max:function(n,t){return this.$push(n,t).reduce(function(n,t){return h(n)||t>n?t:n},void 0)},$min:function(n,t){return this.$push(n,t).reduce(function(n,t){return h(n)||t<n?t:n},void 0)},$avg:function(n,t){var e=this.$push(n,t).filter(i);return e.reduce(function(n,t){return n+t},0)/(e.length||1)},$push:function(n,t){return h(t)?n:n.map(function(n){return un(n,t,null)})},$first:function(n,t){return n.length>0?un(n[0],t):void 0},$last:function(n,t){return n.length>0?un(n[n.length-1],t):void 0},$stdDevPop:function(n,t){return an({data:this.$push(n,t).filter(i),sampled:!1})},$stdDevSamp:function(n,t){return an({data:this.$push(n,t).filter(i),sampled:!0})}},vn={$:function(n,t,e){O("$ not implemented")},$elemMatch:function(n,t,e){var r=X(n,e),u=new _n(t);if(!h(r)&&a(r))for(var o=0;o<r.length;o++)if(u.test(r[o]))return[r[o]]},$slice:function(n,t,e){var r=X(n,e);return a(r)?a(t)?on(r,t[0],t[1]):i(t)?on(r,t):void O("Invalid argument type for $slice projection operator"):r},$stdDevPop:function(n,t,e){return an({data:un(n,t,e),sampled:!1})},$stdDevSamp:function(n,t,e){return an({data:un(n,t,e),sampled:!0})}},hn={$addFields:function(e,r){var u=w(r);return e.map(function(e){return e=t(e),M(u,function(t){var u=r[t],o=void 0;if(l(u)){var i=w(u),a=i.filter(function(n){return 0===n.indexOf("$")});b(a)||(n(1===i.length,"Can have only one root operator in $addFields"),a=a[0],u=u[a],o=un(e,u,a))}else o=un(e,u,null);nn(e,t,function(n,t){n[t]=o},!0)}),e})},$group:function(n,t){var e=t[K()],r=F(n,function(n){return un(n,e,e)}),u=[];return delete t[K()],M(r.keys,function(n,e){var o={};d(n)||(o[K()]=n),M(t,function(n,t){o[t]=B(r.groups[e],t,n)}),u.push(o)}),u},$lookup:function(e,r){function u(n){return C(h(n)?null:n)}var i=r.from,l=r.localField,s=r.foreignField,c=r.as,f="Invalid $lookup expression. ";n(a(i),f+"'from' must be an array"),n(o(s),f+"'foreignField' must be a string"),n(o(l),f+"'localField' must be a string"),n(o(c),f+"'as' must be a string");var v=[],p={};if(i.length<=e.length)M(i,function(n,t){var e=u(n[s]);p[e]=p[e]||[],p[e].push(t)}),M(e,function(n){var e=u(n[l]),r=p[e]||[],o=t(n);o[c]=r.map(function(n){return t(i[n])}),v.push(o)});else{M(e,function(n,t){var e=u(n[l]);p[e]=p[e]||[],p[e].push(t)});var d={};M(i,function(n){var r=u(n[s]);M(p[r]||[],function(r){var u=d[r]||t(e[r]);u[c]=u[c]||[],u[c].push(t(n)),d[r]=u})});for(var g=0,$=w(d).length;g<$;g++)v.push(d[g])}return v},$match:function(n,t){return new _n(t).find(n).all()},$project:function(e,r){if(b(r))return e;var u=[],a=w(r),s=!1,c=K(),f=[!1,!1];if(M(r,function(t,e){e!==c&&(0===t||!1===t?f[0]=!0:f[1]=!0,n(f[0]!==f[1],"Projection cannot have a mix of inclusion and exclusion."))}),g(a,c)){var v=r[c];0!==v&&!1!==v||(a=a.filter($.bind(null,[c])),n($(a,c),"Must not contain collections id key"),s=b(a))}else a.push(c);return M(e,function(n){var e={},f=!1,v=!1,h=[];s&&h.push(c),M(a,function(u){var a=r[u],s=void 0;if(u!==c&&0===a&&(v=!0),u===c&&b(a))s=n[u];else if(o(a))s=un(n,a,u);else if(1===a||!0===a);else{if(!l(a))return void h.push(u);var p=w(a);p=!(p.length>1)&&p[0],g(H(Fn),p)?"$slice"===p?_(a[p]).every(i)?(s=vn[p](n,a[p],u),f=!0):s=un(n,a,u):s=vn[p](n,a[p],u):s=un(n,a,u)}var $=t(Z(n,u));d($)||Object.assign(e,$),d(s)||tn(e,u,t(s))}),(f||v||s)&&(e=Object.assign(t(n),e),M(h,function(n){return en(e,n)})),u.push(e)}),u},$limit:function(n,t){return n.slice(0,t)},$skip:function(n,t){return n.slice(t)},$unwind:function(e,r){var u=[],o=r.substr(1);return M(e,function(e){var r=W(e,o);n(a(r),"Target field '"+o+"' is not of type Array."),M(r,function(n){var r=t(e);r[o]=n,u.push(r)})}),u},$sort:function(n,t){if(!b(t)&&l(t)){M(w(t).reverse(),function(e){var r=F(n,function(n){return X(n,e)}),u={},o=function(n){return u[C(n)]},i=D(r.keys,function(n,t){return u[C(n)]=t,n});-1===t[e]&&i.reverse(),n=[],M(i,function(t){return R(n,r.groups[o(t)])})})}return n},$sortByCount:function(n,t){var e={count:{$sum:1}};return e[K()]=t,this.$sort(this.$group(n,e),{count:-1})},$sample:function(t,e){var r=e.size;n(i(r),"$sample size must be a positive integer");for(var u=[],o=t.length,a=0;a<r;a++){var l=Math.floor(Math.random()*o);u.push(t[l])}return u},$count:function(t,e){n(o(e)&&""!==e.trim()&&-1===e.indexOf(".")&&"$"!==e.trim()[0],"Invalid expression value for $count");var r={};return r[e]=t.length,r},$replaceRoot:function(t,e){var r=e.newRoot,u=[];return M(t,function(t){t=un(t,r,null),n(l(t),"$replaceRoot expression must return a valid JS object"),u.push(t)}),u},$redact:function(n,e){return n.map(function(n){return ln(t(n),e)})},$bucket:function(t,r){var u=r.boundaries,o=r.default,i=u[0],a=u[u.length-1],l=r.output||{count:{$sum:1}};n(u.length>2,"$bucket 'boundaries' expression must have at least 3 elements");for(var s=e(i),c=0,f=u.length-1;c<f;c++)n(s===e(u[c+1]),"$bucket 'boundaries' must all be of the same type"),n(u[c]<u[c+1],"$bucket 'boundaries' must be sorted in ascending order");h(o)||e(r.default)!==e(i)||n(i>r.default||a<r.default,"$bucket 'default' expression must be out of boundaries range");var v={};return M(u,function(n){return v[n]=[]}),h(o)||(v[o]=[]),M(t,function(t){var e=un(t,r.groupBy,null);if(h(e)||e<i||e>=a)n(!h(o),"$bucket require a default for out of range values"),v[o].push(t);else if(e>=i&&e<a){var l=U(u,e),s=u[Math.max(0,l-1)];v[s].push(t)}else O("$bucket 'groupBy' expression must resolve to a value in range of boundaries")}),u.pop(),h(o)||u.push(o),A(u,function(n){var t=B(v[n],null,l);return Object.assign(t,{_id:n})})},$bucketAuto:function(t,e){var r=e.output||{count:{$sum:1}},u=e.groupBy,o=(e.granularity,e.buckets);n(o>0,"The $bucketAuto 'buckets' field must be greater than 0, but found: "+o);var i=Math.round(t.length/o);i<1&&(i=1);for(var a=L(un),l={},s=[],c=D(t,function(n){var t=a(n,u,null);return h(t)?s.push(n):(l[t]||(l[t]=[]),l[t].push(n)),t}),f=[],v=0,p=0,d=c.length;p<o&&v<d;p++){for(var g={},$=[],y=0;y<i&&v<d;y++){var m=a(c[v],u,null);if(h(m)&&(m=null),R($,h(m)?s:l[m]),v+=h(m)?s.length:l[m].length,x(g,"min")||(g.min=m),f.length>0){f[f.length-1]._id.max=g.min}}p==o-1&&R($,c.slice(v)),f.push(Object.assign(B($,null,r),{_id:g}))}return f.length>0&&(f[f.length-1]._id.max=a(c[c.length-1],u,null)),f},$facet:function(n,t){return A(t,function(t){return Y(n,t)})}},pn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},dn=function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")},gn=function(){function n(n,t){for(var e=0;e<t.length;e++){var r=t[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}}(),$n=function(){function n(t){dn(this,n),this.__operators=t}return gn(n,[{key:"run",value:function(n,t){return b(this.__operators)||M(this.__operators,function(e){var r=w(e);1===r.length&&g(H(Dn),r[0])?(r=r[0],n=t instanceof _n?hn[r].call(t,n,e[r]):hn[r](n,e[r])):O("Invalid aggregation operator '"+r+"'")}),n}}]),n}(),yn=function(){function t(n,e,r){dn(this,t),this.__query=e,this.__collection=n,this.__projection=r||e.__projection,this.__operators={},this.__result=!1,this.__position=0}return gn(t,[{key:"_fetch",value:function(){var t=this;if(!1!==this.__result)return this.__result;l(this.__projection)&&Object.assign(this.__operators,{$project:this.__projection}),n(a(this.__collection),"Input collection is not of valid type. Must be an Array."),this.__result=this.__collection.filter(this.__query.test,this.__query);var e=[];if(M(["$sort","$skip","$limit","$project"],function(n){if(x(t.__operators,n)){var r={};r[n]=t.__operators[n],e.push(r)}}),e.length>0){var r=new $n(e);this.__result=r.run(this.__result,this.__query)}return this.__result}},{key:"all",value:function(){return this._fetch()}},{key:"first",value:function(){return this.count()>0?this._fetch()[0]:null}},{key:"last",value:function(){return this.count()>0?this._fetch()[this.count()-1]:null}},{key:"count",value:function(){return this._fetch().length}},{key:"skip",value:function(n){return Object.assign(this.__operators,{$skip:n}),this}},{key:"limit",value:function(n){return Object.assign(this.__operators,{$limit:n}),this}},{key:"sort",value:function(n){return Object.assign(this.__operators,{$sort:n}),this}},{key:"next",value:function(){return this.hasNext()?this._fetch()[this.__position++]:null}},{key:"hasNext",value:function(){return this.count()>this.__position}},{key:"max",value:function(n){return fn.$max(this._fetch(),n)}},{key:"min",value:function(n){return fn.$min(this._fetch(),n)}},{key:"map",value:function(n){return this._fetch().map(n)}},{key:"forEach",value:function(n){M(this._fetch(),n)}},{key:Symbol.iterator,value:function(){var n=this;return{next:function(){return n.hasNext()?{done:!1,value:n.next()}:{done:!0}}}}}]),t}(),mn={$eq:function(n,t){if(S(n,t))return!0;if(h(n)&&h(t))return!0;if(a(n)){if(!k(n,{isMulti:!0}))return-1!==n.findIndex(S.bind(null,t));try{for(var e=0;e<n.length;e++)if(this.$eq(n[e],t))return!0}finally{N(n)}}return!1},$ne:function(n,t){return!this.$eq(n,t)},$in:function(n,t){return n=_(n),E(n,t).length>0},$nin:function(n,t){return h(n)||!this.$in(n,t)},$lt:function(n,t){return void 0!==(n=_(n).find(function(n){return n<t}))},$lte:function(n,t){return void 0!==(n=_(n).find(function(n){return n<=t}))},$gt:function(n,t){return void 0!==(n=_(n).find(function(n){return n>t}))},$gte:function(n,t){return void 0!==(n=_(n).find(function(n){return n>=t}))},$mod:function(n,t){return void 0!==(n=_(n).find(function(n){return i(n)&&a(t)&&2===t.length&&n%t[0]===t[1]}))},$regex:function(n,t){return void 0!==(n=_(n).find(function(n){return o(n)&&f(t)&&!!n.match(t)}))},$exists:function(n,t){return(!1===t||0===t)&&h(n)||(!0===t||1===t)&&!h(n)},$all:function(n,t){var e=!1;if(a(n)&&a(t))for(var r=0,u=t.length;r<u;r++){if(!l(t[r])||!g(w(t[r]),"$elemMatch"))return E(t,n).length===u;e=e||this.$elemMatch(n,t[r].$elemMatch)}return e},$size:function(n,t){return a(n)&&i(t)&&n.length===t},$elemMatch:function(n,t){if(a(n)&&!b(n))for(var e=new _n(t),r=0,u=n.length;r<u;r++)if(e.test(n[r]))return!0;return!1},$type:function(n,t){switch(t){case 1:case"double":return i(n)&&-1!==(n+"").indexOf(".");case 2:case"string":case 5:case"bindata":return o(n);case 3:case"object":return l(n);case 4:case"array":return a(n);case 6:case"undefined":return h(n);case 8:case"bool":return u(n);case 9:case"date":return c(n);case 10:case"null":return p(n);case 11:case"regex":return f(n);case 16:case"int":return i(n)&&n<=2147483647&&-1===(n+"").indexOf(".");case 18:case"long":return i(n)&&n>2147483647&&n<=0x8000000000000000&&-1===(n+"").indexOf(".");case 19:case"decimal":return i(n);default:return!1}}},bn={$and:function(t,e){n(a(e),"Invalid expression: $and expects value to be an Array");var r=[];return M(e,function(n){return r.push(new _n(n))}),{test:function(n){for(var t=0;t<r.length;t++)if(!r[t].test(n))return!1;return!0}}},$or:function(t,e){n(a(e),"Invalid expression. $or expects value to be an Array");var r=[];return M(e,function(n){return r.push(new _n(n))}),{test:function(n){for(var t=0;t<r.length;t++)if(r[t].test(n))return!0;return!1}}},$nor:function(t,e){n(a(e),"Invalid expression. $nor expects value to be an Array");var r=this.$or("$or",e);return{test:function(n){return!r.test(n)}}},$not:function(n,t){var e={};e[n]=rn(t);var r=new _n(e);return{test:function(n){return!r.test(n)}}},$where:function(n,t){return v(t)||(t=new Function("return "+t+";")),{test:function(n){return!0===t.call(n)}}}};M(mn,function(n,t){bn[t]=function(n,t){return function(e,r){return{test:function(u){var o=X(u,e);return n.call(t,o,r)}}}}(n,mn)});var _n=function(){function t(n){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};dn(this,t),this.__criteria=n,this.__projection=e,this.__compiled=[],this._compile()}return gn(t,[{key:"_compile",value:function(){var t=this;if(!b(this.__criteria)){n(l(this.__criteria),"Criteria must be of type Object");var e=void 0;M(this.__criteria,function(n,r){"$where"===r?e={field:r,expr:n}:g(["$and","$or","$nor"],r)?t._processOperator(r,r,n):(n=rn(n),M(n,function(n,e){t._processOperator(r,e,n)})),l(e)&&t._processOperator(e.field,e.field,e.expr)})}}},{key:"_processOperator",value:function(n,t,e){g(H(Rn),t)?this.__compiled.push(bn[t](n,e)):O("Invalid query operator '"+t+"' detected")}},{key:"test",value:function(n){for(var t=0,e=this.__compiled.length;t<e;t++)if(!this.__compiled[t].test(n))return!1;return!0}},{key:"find",value:function(n,t){return new yn(n,this,t)}},{key:"remove",value:function(n){var t=this;return n.reduce(function(n,e){return t.test(e)||n.push(e),n},[])}}]),t}(),xn={$abs:function(n,t){var e=un(n,t,null);return null===e||void 0===e?null:Math.abs(e)},$add:function(n,t){return un(n,t,null).reduce(function(n,t){return n+t},0)},$ceil:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r),"$ceil must be a valid expression that resolves to a number."),Math.ceil(r))},$divide:function(n,t){var e=un(n,t,null);return e[0]/e[1]},$exp:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r),"$exp must be a valid expression that resolves to a number."),Math.exp(r))},$floor:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r),"$floor must be a valid expression that resolves to a number."),Math.floor(r))},$ln:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r),"$ln must be a valid expression that resolves to a number."),Math.log(r))},$log:function(t,e){var r=un(t,e,null);return n(a(r)&&2===r.length,"$log must be a valid expression that resolves to an array of 2 items"),r.some(isNaN)?NaN:r.some(h)?null:(n(r.every(i),"$log expression must resolve to array of 2 numbers"),Math.log10(r[0])/Math.log10(r[1]))},$log10:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r),"$log10 must be a valid expression that resolves to a number."),Math.log10(r))},$mod:function(n,t){var e=un(n,t,null);return e[0]%e[1]},$multiply:function(n,t){return un(n,t,null).reduce(function(n,t){return n*t},1)},$pow:function(t,e){var r=un(t,e,null);return n(a(r)&&2===r.length&&r.every(i),"$pow must be a valid expression that resolves to an array of 2 numbers"),n(!(0===r[0]&&r[1]<0),"$pow cannot raise 0 to a negative exponent"),Math.pow(r[0],r[1])},$sqrt:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r)&&r>0,"$sqrt must be a valid expression that resolves to a non-negative number."),Math.sqrt(r))},$subtract:function(n,t){var e=un(n,t,null);return e[0]-e[1]},$trunc:function(t,e){var r=un(t,e,null);return isNaN(r)?NaN:h(r)?null:(n(i(r)&&r>0,"$trunc must be a valid expression that resolves to a non-negative number."),Math.trunc(r))}},On={$arrayElemAt:function(t,e){var r=un(t,e,null);n(a(r)&&2===r.length,"$arrayElemAt expression must resolve to an array of 2 elements"),n(a(r[0]),"First operand to $arrayElemAt must resolve to an array"),n(i(r[1]),"Second operand to $arrayElemAt must resolve to an integer");var u=r[1];return r=r[0],u<0&&Math.abs(u)<=r.length?r[u+r.length]:u>=0&&u<r.length?r[u]:void 0},$concatArrays:function(t,e){var r=un(t,e,null);return n(a(r)&&2===r.length,"$concatArrays expression must resolve to an array of 2 elements"),r.some(h)?null:r[0].concat(r[1])},$filter:function(t,e){var r=un(t,e.input,null),u=e.as,o=e.cond;return n(a(r),"'input' expression for $filter must resolve to an array"),r.filter(function(n){var t={};return t["$"+u]=n,!0===un(t,o,null)})},$indexOfArray:function(t,e){var r=un(t,e,null);if(h(r))return null;var u=r[0];if(h(u))return null;n(a(u),"First operand for $indexOfArray must resolve to an array.");var o=r[1];if(h(o))return null;var i=r[2]||0,l=r[3]||u.length;return l<u.length&&(u=u.slice(i,l)),u.indexOf(o,i)},$isArray:function(n,t){return a(un(n,t,null))},$range:function(n,t){for(var e=un(n,t,null),r=e[0],u=e[1],o=e[2]||1,i=[];r<u&&o>0||r>u&&o<0;)i.push(r),r+=o;return i},$reverseArray:function(t,e){var r=un(t,e,null);if(h(r))return null;n(a(r),"$reverseArray expression must resolve to an array");for(var u=[],o=r.length-1;o>-1;o--)u.push(r[o]);return u},$reduce:function(t,e){var r=un(t,e.input,null),u=un(t,e.initialValue,null),o=e.in;return h(r)?null:(n(a(r),"'input' expression for $reduce must resolve to an array"),r.reduce(function(n,t){return un({$value:n,$this:t},o,null)},u))},$size:function(n,t){var e=un(n,t,null);return a(e)?e.length:void 0},$slice:function(n,t){var e=un(n,t,null);return on(e[0],e[1],e[2])},$zip:function(t,e){var r=un(t,e.inputs,null),o=e.useLongestLength||!1;n(a(r),"'inputs' expression must resolve to an array"),n(u(o),"'useLongestLength' must be a boolean"),a(e.defaults)&&n(y(o),"'useLongestLength' must be set to true to use 'defaults'");for(var i=0,l=0,s=r.length;l<s;l++){var c=r[l];if(h(c))return null;n(a(c),"'inputs' expression values must resolve to an array or null"),i=o?Math.max(i,c.length):Math.min(i||c.length,c.length)}for(var f=[],v=e.defaults||[],p=0;p<i;p++)!function(n){var t=r.map(function(t,e){return h(t[n])?v[e]||null:t[n]});f.push(t)}(p);return f}},wn={$and:function(n,t){var e=un(n,t,null);return y(e)&&e.every(y)},$or:function(n,t){var e=un(n,t,null);return y(e)&&e.some(y)},$not:function(n,t){return!un(n,t[0],null)}},jn={$cmp:function(n,t){var e=un(n,t,null);return e[0]>e[1]?1:e[0]<e[1]?-1:0}};M(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"],function(n){jn[n]=function(t,e){var r=un(t,e,null);return mn[n](r[0],r[1])}});var kn={$cond:function(t,e){var r=void 0,u=void 0,o=void 0;return a(e)?(n(3===e.length,"Invalid arguments for $cond operator"),r=e[0],u=e[1],o=e[2]):l(e)&&(r=e.if,u=e.then,o=e.else),un(t,r,null)?un(t,u,null):un(t,o,null)},$switch:function(t,e){n(e.branches,"Invalid arguments for $switch operator");var r=e.branches.find(function(e){return n(e.case&&e.then,"Invalid arguments for $switch operator"),un(t,e.case,null)});return r?un(t,r.then,null):e.default?un(t,e.default,null):void O("Invalid arguments for $switch operator")},$ifNull:function(t,e){n(a(e)&&2===e.length,"Invalid arguments for $ifNull operator");var r=un(t,e,null);return null===r[0]||void 0===r[0]?r[1]:r[0]}},Nn={"%Y":["$year",4],"%m":["$month",2],"%d":["$dayOfMonth",2],"%H":["$hour",2],"%M":["$minute",2],"%S":["$second",2],"%L":["$millisecond",3],"%j":["$dayOfYear",3],"%w":["$dayOfWeek",1],"%U":["$week",2],"%%":"%"},Mn={$dayOfYear:function(n,t){var e=un(n,t,null);if(c(e)){var r=new Date(e.getFullYear(),0,0),u=e-r;return Math.round(u/864e5)}},$dayOfMonth:function(n,t){var e=un(n,t,null);return c(e)?e.getDate():void 0},$dayOfWeek:function(n,t){var e=un(n,t,null);return c(e)?e.getDay()+1:void 0},$year:function(n,t){var e=un(n,t,null);return c(e)?e.getFullYear():void 0},$month:function(n,t){var e=un(n,t,null);return c(e)?e.getMonth()+1:void 0},$week:function(n,t){var e=un(n,t,null);e=new Date(+e),e.setHours(0,0,0),e.setDate(e.getDate()+4-(e.getDay()||7));var r=new Date(e.getFullYear(),0,1);return Math.floor(((e-r)/864e5+1)/7)},$hour:function(n,t){var e=un(n,t,null);return c(e)?e.getUTCHours():void 0},$minute:function(n,t){var e=un(n,t,null);return c(e)?e.getMinutes():void 0},$second:function(n,t){var e=un(n,t,null);return c(e)?e.getSeconds():void 0},$millisecond:function(n,t){var e=un(n,t,null);return c(e)?e.getMilliseconds():void 0},$dateToString:function(n,t){for(var e=t.format,r=un(n,t.date,null),u=e.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g),o=0,i=u.length;o<i;o++){var l=Nn[u[o]],s=l;if(a(l)){var c=this[l[0]],f=l[1];s=G(c.call(this,n,r),f)}e=e.replace(u[o],s)}return e}},An={$literal:function(n,t){return t}},En={$setEquals:function(n,t){var e=un(n,t,null),r=q(e[0]),u=q(e[1]);return r.length===u.length&&r.length===E(r,u).length},$setIntersection:function(n,t){var e=un(n,t,null);return E(e[0],e[1])},$setDifference:function(n,t){var e=un(n,t,null);return e[0].filter($.bind(null,e[1]))},$setUnion:function(n,t){var e=un(n,t,null);return I(e[0],e[1])},$setIsSubset:function(n,t){var e=un(n,t,null);return E(e[0],e[1]).length===e[0].length},$anyElementTrue:function(n,t){return un(n,t,null)[0].some(y)},$allElementsTrue:function(n,t){return un(n,t,null)[0].every(y)}},In={$concat:function(n,t){var e=un(n,t,null);return[null,void 0].some(g.bind(null,e))?null:e.join("")},$indexOfBytes:function(t,e){var r=un(t,e,null);if(h(r[0]))return null | ||
;n(o(r[0]),"$indexOfBytes first operand must resolve to a string"),n(o(r[1]),"$indexOfBytes second operand must resolve to a string");var u=r[0],a=r[1],l=r[2],s=r[3];if(n(h(l)||i(l)&&l>=0&&Math.round(l)===l,"$indexOfBytes third operand must resolve to a non-negative integer"),l=l||0,n(h(s)||i(s)&&s>=0&&Math.round(s)===s,"$indexOfBytes fourth operand must resolve to a non-negative integer"),s=s||u.length,l>s)return-1;var c=u.substring(l,s).indexOf(a);return c>-1?c+l:c},$split:function(t,r){var u=un(t,r,null);return n(o(u[0]),"$split requires an expression that evaluates to a string as a first argument, found: "+e(u[0])),n(o(u[1]),"$split requires an expression that evaluates to a string as a second argument, found: "+e(u[1])),u[0].split(u[1])},$strcasecmp:function(n,t){var e=un(n,t,null);return e[0]=b(e[0])?"":e[0].toUpperCase(),e[1]=b(e[1])?"":e[1].toUpperCase(),e[0]>e[1]?1:e[0]<e[1]?-1:0},$substr:function(n,t){var e=un(n,t,null);return o(e[0])?e[1]<0?"":e[2]<0?e[0].substr(e[1]):e[0].substr(e[1],e[2]):""},$toLower:function(n,t){var e=un(n,t,null);return b(e)?"":e.toLowerCase()},$toUpper:function(n,t){var e=un(n,t,null);return b(e)?"":e.toUpperCase()}},Sn={$map:function(t,e){var r=un(t,e.input,null);n(a(r),"Input expression for $map must resolve to an array");var u=e.as,o=e.in,i="$"+u,l=t[i];return r.map(function(n){t[i]=n;var e=un(t,o,null);return d(l)?delete t[i]:t[i]=l,e})},$let:function(n,t){var e=t.vars,r=t.in,u={},o=w(e);M(o,function(t){var r=un(n,e[t],null),o="$"+t;u[o]=n[o],n[o]=r});var i=un(n,r,null);return M(o,function(t){var e="$"+t;d(u[e])?delete n[e]:n[e]=u[e]}),i}},qn=Object.assign({},xn,On,wn,jn,kn,Mn,An,En,In,Sn),Pn={aggregate:qn,group:fn,pipeline:hn,projection:vn,query:bn},Tn="aggregate",Cn="group",Dn="pipeline",Fn="projection",Rn="query",Un={key:"_id"},Ln={$$ROOT:function(n,t,e){return e.root},$$CURRENT:function(n,t,e){return n}},Bn={$$KEEP:function(n){return n},$$PRUNE:function(){},$$DESCEND:function(n,t,e){if(!x(t,"$cond"))return n;var r=void 0;return M(n,function(u,o){s(u)&&(a(u)?(r=[],M(u,function(n){l(n)&&(n=ln(n,t,e)),h(n)||r.push(n)})):r=ln(u,t,e),h(r)?delete n[o]:n[o]=r)}),n}},Yn=w(Ln),Jn=w(Bn);return{_internal:sn,Aggregator:$n,CollectionMixin:{query:function(n,t){return new _n(n).find(this.toJSON(),t)},aggregate:function(n){return new $n(n).run(this.toJSON())}},Cursor:yn,OP_AGGREGATE:Tn,OP_GROUP:Cn,OP_PIPELINE:Dn,OP_PROJECTION:Fn,OP_QUERY:Rn,Query:_n,VERSION:"1.3.2",addOperators:Q,aggregate:Y,find:J,remove:z,setup:V}}); | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.mingo=t()}(this,function(){"use strict";function n(n,t){b(n)&&w(t)}function t(n){switch(e(n)){case mn:return n.map(t);case bn:return E(n,t);default:return n}}function r(n){return null===n?"Null":void 0===n?"Undefined":n.constructor.name}function e(n){return r(n).toLowerCase()}function u(n){return e(n)===pn}function i(n){return e(n)===gn}function o(n){return e(n)===dn}function a(n){return e(n)===mn}function s(n){return!p(n)&&O(n,"length")}function c(n){return e(n)===bn}function f(n){return n===Object(n)}function l(n){return e(n)===$n}function v(n){return e(n)===yn}function h(n){return e(n)===_n}function p(n){return d(n)||g(n)}function d(n){return e(n)===vn}function g(n){return e(n)===hn}function $(n,t){return n.includes(t)}function y(n,t){return!n.includes(t)}function m(n){return!!n}function b(n){return!n}function _(n){return p(n)||a(n)&&0===n.length||c(n)&&0===j(n).length||!n}function x(n){return a(n)?n:[n]}function O(n,t){return n.hasOwnProperty(t)}function w(n){throw new Error(n)}function j(n){return Object.keys(n)}function k(n,t){n[Nn]=Object.assign(n[Nn]||{},t)}function N(n,t){return O(n,Nn)&&c(t)&&q(Object.assign({},n[Nn],t),n[Nn])}function M(n){O(n,Nn)&&delete n[Nn]}function A(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(n(t===Object(t),"Cannot iterate over object of type '"+e(t)+"'"),s(t))for(var i=0,o=t.length;i<o&&!1!==r.call(u,t[i],i,t);i++);else for(var a in t)if(O(t,a)&&!1===r.call(u,t[a],a,t))break}function E(n,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(a(n))return n.map(t,r);if(c(n)){var e={};return A(n,function(n,u){return e[u]=t.call(r,n,u)},n),e}}function S(n,t,r){return a(n)?n.reduce(t,r):(A(n,function(e,u){return r=t(r,e,u,n)}),r)}function I(n,t){return n.filter($.bind(null,t))}function T(n,t){return L(L([],n),t.filter(y.bind(null,n)))}function q(n,t){if(n===t)return!0;var r=e(n);if(r!==e(t)||r===_n)return!1;if(r===dn&&isNaN(n)&&isNaN(t))return!0;if($([$n,yn],r))return n.toString()===t.toString();if(r===mn){if(n.length===t.length&&0===n.length)return!0;if(n.length!==t.length)return!1;for(var u=0,i=n.length;u<i;u++)if(!q(n[u],t[u]))return!1}else{if(r!==bn)return R(n)===R(t);var o=j(n),a=j(t);if(o.length!==a.length)return!1;if(o.sort(),a.sort(),!q(o,a))return!1;for(var s=0,c=o.length;s<c;s++){var f=o[s];if(!q(n[f],t[f]))return!1}}return!0}function P(n){var t={},r=[];return A(n,function(n){var e=R(n);O(t,e)||(r.push(n),t[e]=0)}),r}function C(n){return(Math.E+Math.random()).toString(36).slice(2,n+2)}function D(n){var t=e(n);switch(t){case _n:return C(7);case pn:case dn:case yn:return n.toString();case gn:return JSON.stringify(n);case $n:return n.toISOString();case vn:case hn:return t;case mn:return"["+E(n,function(n){return""+D(n)})+"]";default:var u=t===bn?"":r(n)+"|",i=j(n);return i.sort(),u+"{"+E(i,function(t){return D(t)+":"+D(n[t])})+"}"}}function R(n){var t=0,r=void 0,e=void 0,u=void 0,i=D(n);if(0===i.length)return t;for(r=0,u=i.length;r<u;r++)e=i.charCodeAt(r),t=(t<<5)-t+e,t|=0;return t.toString()}function F(n,t){for(var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,e={},u=[],i=n.length,o=[],a=0;a<i;a++){var s=n[a],c=t.call(r,s,a);if(p(c))o.push(s);else{var f=R(s);O(e,f)||(e[f]=[c,a]),u.push(s)}}return u.sort(function(n,t){var r=e[R(n)],u=e[R(t)];return r[0]<u[0]?-1:r[0]>u[0]?1:r[1]<u[1]?-1:r[1]>u[1]?1:0}),L(o,u)}function U(n,t,r){var e={keys:[],groups:[]},u={};return A(n,function(n){var i=t.call(r,n),o=R(i),a=-1;g(u[o])&&(a=e.keys.length,u[o]=a,e.keys.push(i),e.groups.push([])),a=u[o],e.groups[a].push(n)}),e}function L(n,t){return Array.prototype.push.apply(n,t),n}function B(n,t){for(var r=0,e=n.length-1;r<=e;){var u=Math.round(r+(e-r)/2);if(t<n[u])e=u-1;else{if(!(t>n[u]))return u;r=u+1}}return r}function Y(n){var t=this;return function(r){return function(){for(var e=arguments.length,u=Array(e),i=0;i<e;i++)u[i]=arguments[i];var o=R(u);return O(r,o)||(r[o]=n.apply(t,u)),r[o]}}({})}function J(t,r,e){if($(V(wn),r))return Mn[r](t,e);if(c(e)){var u={};return A(e,function(r,i){if(u[i]=J(t,i,e[i]),$(V(wn),i))return u=u[i],n(1===j(e).length,"Invalid $group expression '"+JSON.stringify(e)+"'"),!1}),u}}function z(t,r){return n(a(r),"Aggregation pipeline must be an array"),new qn(r).run(t)}function G(n,t,r){return new Rn(t).find(n,r)}function H(n,t){return new Rn(t).remove(n)}function Q(n,t){return new Array(Math.max(t-String(n).length+1,0)).join("0")+n}function V(){return S(arguments,function(n,t){return L(n,j(Wn[t]))},[])}function K(t,r){var e=r(ln());n(O(Wn,t),"Invalid operator class "+t);var i=Wn[t];A(e,function(r,e){n(/^\$\w+$/.test(e),"Invalid operator name "+e),n(!O(i,e),e+" already exists for '"+t+"' operators")});var o={};switch(t){case kn:A(e,function(n,t){o[t]=function(n,r){return function(e,i){return{test:function(o){var a=nn(o,e),s=n.call(r,e,a,i);return u(s)?s:s instanceof Rn?s.test(o):void w("Invalid return type for '"+t+"'. Must return a Boolean or Query")}}}}(n,e)});break;case jn:A(e,function(n,t){o[t]=function(n,t){return function(r,e,u){var i=nn(r,u);return n.call(t,u,i,e)}}(n,e)});break;default:A(e,function(n,t){o[t]=function(n,t){return function(){for(var r=arguments.length,e=Array(r),u=0;u<r;u++)e[u]=arguments[u];return n.apply(t,e)}}(n,e)})}Object.assign(Wn[t],o)}function W(n){Object.assign(Xn,n||{})}function X(){return Xn.key}function Z(n,t){return n[t]}function nn(n,t){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],e=t.split("."),u=n;n:for(var i=0;i<e.length;i++){var o=function(n){if(null===e[n].match(/^\d+$/)&&a(u)){if(!0===r&&0===n)return{v:u};u=u.map(function(t){return nn(t,e[n],!0)}),k(u,{isMulti:!0}),1===u.length&&(u=u[0])}else u=Z(u,e[n]),r=!1;if(p(u))return"break"}(i);switch(o){case"break":break n;default:if("object"===(void 0===o?"undefined":Sn(o)))return o.v}}return u}function tn(t,r){if(!p(t)){var e=r.split("."),u=e[0],i=1===e.length||e.slice(1).join("."),o=null!==u.match(/^\d+$/),s=e.length>1,c=void 0,f=void 0;try{a(t)?o?(c=Z(t,u),s&&(c=tn(c,i)),n(!g(c)),c=[c]):(c=[],A(t,function(n){f=tn(n,r),p(f)||c.push(f)}),n(c.length>0)):(f=Z(t,u),s&&(f=tn(f,i)),n(!g(f)),c={},c[u]=f)}catch(n){c=void 0}return c}}function rn(n,t,r){var e=arguments.length>3&&void 0!==arguments[3]&&arguments[3],u=t.split("."),i=u[0],o=1===u.length||u.slice(1).join(".");if(1===u.length)r(n,i);else if(a(n)&&!/^\d+$/.test(i))A(n,function(n){rn(n,t,r,e)});else{if(!0===e){var s=O(n,i);s&&!p(n[i])||(n[i]={})}rn(n[i],o,r,e)}}function en(n,t,r){rn(n,t,function(n,t){n[t]=r},!0)}function un(n,t){rn(n,t,function(n,t){a(n)&&/^\d+$/.test(t)?n.splice(parseInt(t),1):c(n)&&delete n[t]})}function on(n){if($(xn,e(n)))return v(n)?{$regex:n}:{$eq:n};if(f(n)){var t=j(n);if(0===I(V(kn),t).length)return{$eq:n};if($(t,"$regex")){var r=n.$regex,u=n.$options||"",o="";i(r)&&(o+=r.ignoreCase||u.indexOf("i")>=0?"i":"",o+=r.multiline||u.indexOf("m")>=0?"m":"",o+=r.global||u.indexOf("g")>=0?"g":"",r=new RegExp(r,o)),n.$regex=r,delete n.$options}}return n}function an(t,r){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(o.root=o.root||t,$(V(On),u))return Kn[u](t,r,o);if($(V(wn),u))return t=an(t,r,null,o),n(a(t),u+" expression must resolve to an array"),Mn[u](t,null,o);if(i(r)&&r.length>0&&"$"===r[0]){if($(tt,r))return Zn[r](t,null,o);if($(rt,r))return r;var s=tt.filter(function(n){return 0===r.indexOf(n+".")});return 1===s.length&&(s=s[0],"$$ROOT"===s&&(t=o.root),r=r.substr(s.length)),nn(t,r.slice(1))}switch(e(r)){case mn:return r.map(function(n){return an(t,n)});case bn:var c={};return A(r,function(e,u){if(c[u]=an(t,e,u,o),$(V(On,wn),u))return n(1===j(r).length,"Invalid aggregation expression '"+JSON.stringify(r)+"'"),c=c[u],!1}),c;default:return r}}function sn(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return p(e)?r<0?(r=Math.max(0,t.length+r),e=t.length-r+1):(e=r,r=0):(r<0&&(r=Math.max(0,t.length+r)),n(e>0,"Invalid argument value for $slice operator. Limit must be a positive number"),e+=r),Array.prototype.slice.apply(t,[r,e])}function cn(n){var t=S(n.data,function(n,t){return n+t},0),r=n.data.length||1,e=!0===n.sampled?1:0,u=t/(r-e);return Math.sqrt(S(n.data,function(n,t){return n+Math.pow(t-u,2)},0)/r)}function fn(n,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};r.root=r.root||n;var e=an(n,t,null,r);return $(rt,e)?nt[e](n,t,r):e}function ln(){return{computeValue:an,idKey:X,ops:V,resolve:nn,assert:n,clone:t,each:A,err:w,getType:r,has:O,isArray:a,isBoolean:u,isDate:l,isEmpty:_,isEqual:q,isFunction:h,isNil:p,isNull:d,isNumber:o,isObject:c,isRegExp:v,isString:i,isUndefined:g,keys:j,map:E}}Function.prototype.bind||(Function.prototype.bind=function(n){if("function"!=typeof this)throw new Error("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),r=this,e=function(){},u=function(){return r.apply(this instanceof e?this:n,t.concat(Array.prototype.slice.call(arguments)))};return this.prototype&&(e.prototype=this.prototype),u.prototype=new e,u}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),r=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u<r;){var i=t[u];if(n.call(e,i,u,t))return i;u++}}}),Array.prototype.findIndex||Object.defineProperty(Array.prototype,"findIndex",{value:function(n){if(null==this)throw new TypeError('"this" is null or not defined');var t=Object(this),r=t.length>>>0;if("function"!=typeof n)throw new TypeError("predicate must be a function");for(var e=arguments[1],u=0;u<r;){var i=t[u];if(n.call(e,i,u,t))return u;u++}return-1}}),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(n,t){if(null==this)throw new TypeError('"this" is null or not defined');var r=Object(this),e=r.length>>>0;if(0===e)return!1;for(var u=0|t,i=Math.max(u>=0?u:e-Math.abs(u),0);i<e;){if(function(n,t){return n===t||"number"==typeof n&&"number"==typeof t&&isNaN(n)&&isNaN(t)}(r[i],n))return!0;i++}return!1}}),"function"!=typeof Object.assign&&(Object.assign=function(n,t){if(null==n)throw new TypeError("Cannot convert undefined or null to object");for(var r=Object(n),e=Array.prototype.slice.call(arguments),u=1;u<e.length;u++){var i=e[u];if(null!=i)for(var o in i)i.hasOwnProperty(o)&&(r[o]=i[o])}return r}),Object.keys||(Object.keys=function(n){if(n!==Object(n))throw new TypeError("Object.keys called on a non-object");var t=[];for(var r in n)n.hasOwnProperty(r)&&t.push(r);return t}),Object.values||(Object.values=function(n){if(n!==Object(n))throw new TypeError("Object.values called on a non-object");var t=[];for(var r in n)n.hasOwnProperty(r)&&t.push(n[r]);return t});var vn="null",hn="undefined",pn="boolean",dn="number",gn="string",$n="date",yn="regexp",mn="array",bn="object",_n="function",xn=[vn,hn,pn,dn,gn,$n,yn],On="aggregate",wn="group",jn="projection",kn="query",Nn="__mingo__",Mn={$addToSet:function(n,t){return P(this.$push(n,t))},$sum:function(n,t){return a(n)?o(t)?n.length*t:S(this.$push(n,t).filter(o),function(n,t){return n+t},0):0},$max:function(n,t){return S(this.$push(n,t),function(n,t){return p(n)||t>n?t:n},void 0)},$min:function(n,t){return S(this.$push(n,t),function(n,t){return p(n)||t<n?t:n},void 0)},$avg:function(n,t){var r=this.$push(n,t).filter(o);return S(r,function(n,t){return n+t},0)/(r.length||1)},$push:function(n,t){return p(t)?n:E(n,function(n){return an(n,t)})},$first:function(n,t){return n.length>0?an(n[0],t):void 0},$last:function(n,t){return n.length>0?an(n[n.length-1],t):void 0},$stdDevPop:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!1})},$stdDevSamp:function(n,t){return cn({data:this.$push(n,t).filter(o),sampled:!0})}},An={$:function(n,t,r){w("$ not implemented")},$elemMatch:function(n,t,r){var e=nn(n,r),u=new Rn(t);if(!p(e)&&a(e))for(var i=0;i<e.length;i++)if(u.test(e[i]))return[e[i]]},$slice:function(n,t,r){var e=nn(n,r);return a(e)?a(t)?sn(e,t[0],t[1]):o(t)?sn(e,t):void w("Invalid argument type for $slice projection operator"):e},$stdDevPop:function(n,t,r){return cn({data:an(n,t,r),sampled:!1})},$stdDevSamp:function(n,t,r){return cn({data:an(n,t,r),sampled:!0})}},En={$addFields:function(n,r){var e=j(r);return n.map(function(n){return n=t(n),A(e,function(t){var e=r[t],u=an(n,e);rn(n,t,function(n,t){n[t]=u},!0)}),n})},$group:function(n,t){var r=X(),e=t[r],u=U(n,function(n){return an(n,e,e)}),i=[];return delete t[r],A(u.keys,function(n,e){var o={};g(n)||(o[r]=n),A(t,function(n,t){o[t]=J(u.groups[e],t,n)}),i.push(o)}),i},$lookup:function(r,e){function u(n){return R(p(n)?null:n)}var o=e.from,s=e.localField,c=e.foreignField,f=e.as,l="Invalid $lookup expression. ";n(a(o),l+"'from' must be an array"),n(i(c),l+"'foreignField' must be a string"),n(i(s),l+"'localField' must be a string"),n(i(f),l+"'as' must be a string");var v=[],h={};if(o.length<=r.length)A(o,function(n,t){var r=u(n[c]);h[r]=h[r]||[],h[r].push(t)}),A(r,function(n){var r=u(n[s]),e=h[r]||[],i=t(n);i[f]=e.map(function(n){return t(o[n])}),v.push(i)});else{A(r,function(n,t){var r=u(n[s]);h[r]=h[r]||[],h[r].push(t)});var d={};A(o,function(n){var e=u(n[c]);A(h[e]||[],function(e){var u=d[e]||t(r[e]);u[f]=u[f]||[],u[f].push(t(n)),d[e]=u})});for(var g=0,$=j(d).length;g<$;g++)v.push(d[g])}return v},$match:function(n,t){return new Rn(t).find(n).all()},$project:function(r,e){if(_(e))return r;var u=[],a=j(e),s=!1,f=X(),l=[!1,!1];if(A(e,function(t,r){r!==f&&(0===t||!1===t?l[0]=!0:l[1]=!0,n(l[0]!==l[1],"Projection cannot have a mix of inclusion and exclusion."))}),$(a,f)){var v=e[f];0!==v&&!1!==v||(a=a.filter(y.bind(null,[f])),n(y(a,f),"Must not contain collections id key"),s=_(a))}else a.push(f);return A(r,function(n){var r={},l=!1,v=!1,h=[];s&&h.push(f),A(a,function(u){var a=e[u],s=void 0;if(u!==f&&0===a&&(v=!0),u===f&&_(a))s=n[u];else if(i(a))s=an(n,a,u);else if(1===a||!0===a);else{if(!c(a))return void h.push(u);var p=j(a);p=!(p.length>1)&&p[0],$(V(jn),p)?"$slice"===p?x(a[p]).every(o)?(s=An[p](n,a[p],u),l=!0):s=an(n,a,u):s=An[p](n,a[p],u):s=an(n,a,u)}var d=t(tn(n,u));g(d)||Object.assign(r,d),g(s)||en(r,u,t(s))}),(l||v||s)&&(r=Object.assign(t(n),r),A(h,function(n){return un(r,n)})),u.push(r)}),u},$limit:function(n,t){return n.slice(0,t)},$skip:function(n,t){return n.slice(t)},$unwind:function(r,e){var u=[],i=e.substr(1);return A(r,function(r){var e=Z(r,i);n(a(e),"Target field '"+i+"' is not of type Array."),A(e,function(n){var e=t(r);e[i]=n,u.push(e)})}),u},$sort:function(n,t){if(!_(t)&&c(t)){A(j(t).reverse(),function(r){var e=U(n,function(n){return nn(n,r)}),u={},i=function(n){return u[R(n)]},o=F(e.keys,function(n,t){return u[R(n)]=t,n});-1===t[r]&&o.reverse(),n=[],A(o,function(t){return L(n,e.groups[i(t)])})})}return n},$sortByCount:function(n,t){var r={count:{$sum:1}};return r[X()]=t,this.$sort(this.$group(n,r),{count:-1})},$sample:function(t,r){var e=r.size;n(o(e),"$sample size must be a positive integer");for(var u=[],i=t.length,a=0;a<e;a++){var s=Math.floor(Math.random()*i);u.push(t[s])}return u},$count:function(t,r){n(i(r)&&""!==r.trim()&&-1===r.indexOf(".")&&"$"!==r.trim()[0],"Invalid expression value for $count");var e={};return e[r]=t.length,e},$replaceRoot:function(t,r){var e=r.newRoot,u=[];return A(t,function(t){t=an(t,e),n(c(t),"$replaceRoot expression must return a valid JS object"),u.push(t)}),u},$redact:function(n,r){return n.map(function(n){return fn(t(n),r)})},$bucket:function(t,e){var u=e.boundaries,i=e.default,o=u[0],a=u[u.length-1],s=e.output||{count:{$sum:1}};n(u.length>2,"$bucket 'boundaries' expression must have at least 3 elements");for(var c=r(o),f=0,l=u.length-1;f<l;f++)n(c===r(u[f+1]),"$bucket 'boundaries' must all be of the same type"),n(u[f]<u[f+1],"$bucket 'boundaries' must be sorted in ascending order");p(i)||r(e.default)!==r(o)||n(o>e.default||a<e.default,"$bucket 'default' expression must be out of boundaries range");var v={};return A(u,function(n){return v[n]=[]}),p(i)||(v[i]=[]),A(t,function(t){var r=an(t,e.groupBy);if(p(r)||r<o||r>=a)n(!p(i),"$bucket require a default for out of range values"),v[i].push(t);else if(r>=o&&r<a){var s=B(u,r),c=u[Math.max(0,s-1)];v[c].push(t)}else w("$bucket 'groupBy' expression must resolve to a value in range of boundaries")}),u.pop(),p(i)||u.push(i),E(u,function(n){var t=J(v[n],null,s);return Object.assign(t,{_id:n})})},$bucketAuto:function(t,r){var e=r.output||{count:{$sum:1}},u=r.groupBy,i=r.buckets;n(i>0,"The $bucketAuto 'buckets' field must be greater than 0, but found: "+i);var o=Math.round(t.length/i);o<1&&(o=1);for(var a=Y(an),s={},c=[],f=F(t,function(n){var t=a(n,u);return p(t)?c.push(n):(s[t]||(s[t]=[]),s[t].push(n)),t}),l=X(),v=[],h=0,d=0,g=f.length;d<i&&h<g;d++){for(var $={},y=[],m=0;m<o&&h<g;m++){var b=a(f[h],u);if(p(b)&&(b=null),L(y,p(b)?c:s[b]),h+=p(b)?c.length:s[b].length,O($,"min")||($.min=b),v.length>0){v[v.length-1][l].max=$.min}}d==i-1&&L(y,f.slice(h)),v.push(Object.assign(J(y,null,e),{_id:$}))}return v.length>0&&(v[v.length-1][l].max=a(f[f.length-1],u)),v},$facet:function(n,t){return E(t,function(t){return z(n,t)})}},Sn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},In=function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")},Tn=function(){function n(n,t){for(var r=0;r<t.length;r++){var e=t[r];e.enumerable=e.enumerable||!1,e.configurable=!0,"value"in e&&(e.writable=!0),Object.defineProperty(n,e.key,e)}}return function(t,r,e){return r&&n(t.prototype,r),e&&n(t,e),t}}(),qn=function(){function t(n){In(this,t),this.__operators=n}return Tn(t,[{key:"run",value:function(t,r){return _(this.__operators)||A(this.__operators,function(e){var u=j(e);n(1===u.length&&$(V("pipeline"),u[0]),"Invalid aggregation operator "+u),u=u[0],t=r&&r instanceof Rn?En[u].call(r,t,e[u]):En[u](t,e[u])}),t}}]),t}(),Pn=function(){function t(n,r,e){In(this,t),this.__query=r,this.__collection=n,this.__projection=e||r.__projection,this.__operators={},this.__result=!1,this.__position=0}return Tn(t,[{key:"_fetch",value:function(){var t=this;if(!1!==this.__result)return this.__result;c(this.__projection)&&Object.assign(this.__operators,{$project:this.__projection}),n(a(this.__collection),"Input collection is not of valid type. Must be an Array."),this.__result=this.__collection.filter(this.__query.test,this.__query);var r=[];if(A(["$sort","$skip","$limit","$project"],function(n){if(O(t.__operators,n)){var e={};e[n]=t.__operators[n],r.push(e)}}),r.length>0){var e=new qn(r);this.__result=e.run(this.__result,this.__query)}return this.__result}},{key:"all",value:function(){return this._fetch()}},{key:"first",value:function(){return this.count()>0?this._fetch()[0]:null}},{key:"last",value:function(){return this.count()>0?this._fetch()[this.count()-1]:null}},{key:"count",value:function(){return this._fetch().length}},{key:"skip",value:function(n){return Object.assign(this.__operators,{$skip:n}),this}},{key:"limit",value:function(n){return Object.assign(this.__operators,{$limit:n}),this}},{key:"sort",value:function(n){return Object.assign(this.__operators,{$sort:n}),this}},{key:"next",value:function(){return this.hasNext()?this._fetch()[this.__position++]:null}},{key:"hasNext",value:function(){return this.count()>this.__position}},{key:"max",value:function(n){return Mn.$max(this._fetch(),n)}},{key:"min",value:function(n){return Mn.$min(this._fetch(),n)}},{key:"map",value:function(n){return this._fetch().map(n)}},{key:"forEach",value:function(n){A(this._fetch(),n)}},{key:Symbol.iterator,value:function(){var n=this;return{next:function(){return n.hasNext()?{done:!1,value:n.next()}:{done:!0}}}}}]),t}(),Cn={$eq:function(n,t){if(q(n,t))return!0;if(p(n)&&p(t))return!0;if(a(n)){if(!N(n,{isMulti:!0}))return-1!==n.findIndex(q.bind(null,t));try{for(var r=0;r<n.length;r++)if(this.$eq(n[r],t))return!0}finally{M(n)}}return!1},$ne:function(n,t){return!this.$eq(n,t)},$in:function(n,t){return n=x(n),I(n,t).length>0},$nin:function(n,t){return p(n)||!this.$in(n,t)},$lt:function(n,t){return void 0!==(n=x(n).find(function(n){return n<t}))},$lte:function(n,t){return void 0!==(n=x(n).find(function(n){return n<=t}))},$gt:function(n,t){return void 0!==(n=x(n).find(function(n){return n>t}))},$gte:function(n,t){return void 0!==(n=x(n).find(function(n){return n>=t}))},$mod:function(n,t){return void 0!==(n=x(n).find(function(n){return o(n)&&a(t)&&2===t.length&&n%t[0]===t[1]}))},$regex:function(n,t){return void 0!==(n=x(n).find(function(n){return i(n)&&v(t)&&!!n.match(t)}))},$exists:function(n,t){return(!1===t||0===t)&&p(n)||(!0===t||1===t)&&!p(n)},$all:function(n,t){var r=!1;if(a(n)&&a(t))for(var e=0,u=t.length;e<u;e++){if(!c(t[e])||!$(j(t[e]),"$elemMatch"))return I(t,n).length===u;r=r||this.$elemMatch(n,t[e].$elemMatch)}return r},$size:function(n,t){return a(n)&&o(t)&&n.length===t},$elemMatch:function(n,t){if(a(n)&&!_(n))for(var r=new Rn(t),e=0,u=n.length;e<u;e++)if(r.test(n[e]))return!0;return!1},$type:function(n,t){switch(t){case 1:case"double":return o(n)&&-1!==(n+"").indexOf(".");case 2:case gn:return i(n);case 3:case bn:return c(n);case 4:case mn:return a(n);case 6:case hn:return p(n);case 8:case"bool":return u(n);case 9:case $n:return l(n);case 10:case vn:return d(n);case 11:case"regex":return v(n);case 16:case"int":return o(n)&&n<=2147483647&&-1===(n+"").indexOf(".");case 18:case"long":return o(n)&&n>2147483647&&n<=0x8000000000000000&&-1===(n+"").indexOf(".");case 19:case"decimal":return o(n);default:return!1}}},Dn={$and:function(t,r){n(a(r),"Invalid expression: $and expects value to be an Array");var e=[];return A(r,function(n){return e.push(new Rn(n))}),{test:function(n){for(var t=0;t<e.length;t++)if(!e[t].test(n))return!1;return!0}}},$or:function(t,r){n(a(r),"Invalid expression. $or expects value to be an Array");var e=[];return A(r,function(n){return e.push(new Rn(n))}),{test:function(n){for(var t=0;t<e.length;t++)if(e[t].test(n))return!0;return!1}}},$nor:function(t,r){n(a(r),"Invalid expression. $nor expects value to be an Array");var e=this.$or("$or",r);return{test:function(n){return!e.test(n)}}},$not:function(n,t){var r={};r[n]=on(t);var e=new Rn(r);return{test:function(n){return!e.test(n)}}},$where:function(n,t){return h(t)||(t=new Function("return "+t+";")),{test:function(n){return!0===t.call(n)}}}};A(Cn,function(n,t){Dn[t]=function(n,t){return function(r,e){return{test:function(u){var i=nn(u,r);return n.call(t,i,e)}}}}(n,Cn)});var Rn=function(){function t(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};In(this,t),this.__criteria=n,this.__projection=r,this.__compiled=[],this._compile()}return Tn(t,[{key:"_compile",value:function(){var t=this;if(!_(this.__criteria)){n(c(this.__criteria),"Criteria must be of type Object");var r=void 0;A(this.__criteria,function(n,e){"$where"===e?r={field:e,expr:n}:$(["$and","$or","$nor"],e)?t._processOperator(e,e,n):(n=on(n),A(n,function(n,r){t._processOperator(e,r,n)})),c(r)&&t._processOperator(r.field,r.field,r.expr)})}}},{key:"_processOperator",value:function(n,t,r){$(V(kn),t)?this.__compiled.push(Dn[t](n,r)):w("Invalid query operator '"+t+"' detected")}},{key:"test",value:function(n){for(var t=0,r=this.__compiled.length;t<r;t++)if(!this.__compiled[t].test(n))return!1;return!0}},{key:"find",value:function(n,t){return new Pn(n,this,t)}},{key:"remove",value:function(n){var t=this;return S(n,function(n,r){return t.test(r)||n.push(r),n},[])}}]),t}(),Fn={$abs:function(n,t){var r=an(n,t);return null===r||void 0===r?null:Math.abs(r)},$add:function(n,t){return S(an(n,t),function(n,t){return n+t},0)},$ceil:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e),"$ceil must be a valid expression that resolves to a number."),Math.ceil(e))},$divide:function(n,t){var r=an(n,t);return r[0]/r[1]},$exp:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e),"$exp must be a valid expression that resolves to a number."),Math.exp(e))},$floor:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e),"$floor must be a valid expression that resolves to a number."),Math.floor(e))},$ln:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e),"$ln must be a valid expression that resolves to a number."),Math.log(e))},$log:function(t,r){var e=an(t,r);return n(a(e)&&2===e.length,"$log must be a valid expression that resolves to an array of 2 items"),e.some(isNaN)?NaN:e.some(p)?null:(n(e.every(o),"$log expression must resolve to array of 2 numbers"),Math.log10(e[0])/Math.log10(e[1]))},$log10:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e),"$log10 must be a valid expression that resolves to a number."),Math.log10(e))},$mod:function(n,t){var r=an(n,t);return r[0]%r[1]},$multiply:function(n,t){return S(an(n,t),function(n,t){return n*t},1)},$pow:function(t,r){var e=an(t,r);return n(a(e)&&2===e.length&&e.every(o),"$pow expression must resolve to an array of 2 numbers"),n(!(0===e[0]&&e[1]<0),"$pow cannot raise 0 to a negative exponent"),Math.pow(e[0],e[1])},$sqrt:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e)&&e>0,"$sqrt expression must resolve to non-negative number."),Math.sqrt(e))},$subtract:function(n,t){var r=an(n,t);return r[0]-r[1]},$trunc:function(t,r){var e=an(t,r);return isNaN(e)?NaN:p(e)?null:(n(o(e)&&e>0,"$trunc must be a valid expression that resolves to a non-negative number."),Math.trunc(e))}},Un={$arrayElemAt:function(t,r){var e=an(t,r);n(a(e)&&2===e.length,"$arrayElemAt expression must resolve to an array of 2 elements"),n(a(e[0]),"First operand to $arrayElemAt must resolve to an array"),n(o(e[1]),"Second operand to $arrayElemAt must resolve to an integer");var u=e[1];return e=e[0],u<0&&Math.abs(u)<=e.length?e[u+e.length]:u>=0&&u<e.length?e[u]:void 0},$arrayToObject:function(t,r){var e=an(t,r);return n(a(e),"$arrayToObject expression must resolve to an array"),S(e,function(n,t){return a(t)&&2==t.length?n[t[0]]=t[1]:c(t)&&O(t,"k")&&O(t,"v")?n[t.k]=t.v:w("$arrayToObject expression is invalid."),n},{})},$concatArrays:function(t,r){var e=an(t,r,null);return n(a(e)&&2===e.length,"$concatArrays expression must resolve to an array of 2 elements"),e.some(p)?null:e[0].concat(e[1])},$filter:function(t,r){var e=an(t,r.input),u=r.as,i=r.cond;return n(a(e),"$filter 'input' expression must resolve to an array"),e.filter(function(n){var t={};return t["$"+u]=n,!0===an(t,i)})},$in:function(t,r){var e=an(t,r[0]),u=an(t,r[1]);return n(a(u),"$in second argument must be an array"),$(u,e)},$indexOfArray:function(t,r){var e=an(t,r);if(p(e))return null;var u=e[0];if(p(u))return null;n(a(u),"$indexOfArray expression must resolve to an array.");var i=e[1];if(p(i))return null;var o=e[2]||0,s=e[3]||u.length;return s<u.length&&(u=u.slice(o,s)),u.indexOf(i,o)},$isArray:function(n,t){return a(an(n,t))},$map:function(t,r){var e=an(t,r.input);n(a(e),"$map 'input' expression must resolve to an array");var u=r.as,i=r.in,o="$"+u,s=t[o];return E(e,function(n){t[o]=n;var r=an(t,i);return g(s)?delete t[o]:t[o]=s,r})},$objectToArray:function(t,r){var e=an(t,r);n(c(e),"$objectToArray expression must resolve to an object");var u=[];return A(e,function(n,t){return u.push({k:t,v:n})}),u},$range:function(n,t){for(var r=an(n,t),e=r[0],u=r[1],i=r[2]||1,o=[];e<u&&i>0||e>u&&i<0;)o.push(e),e+=i;return o},$reduce:function(t,r){var e=an(t,r.input),u=an(t,r.initialValue),i=r.in;return p(e)?null:(n(a(e),"$reduce 'input' expression must resolve to an array"),S(e,function(n,t){return an({$value:n,$this:t},i)},u))},$reverseArray:function(t,r){var e=an(t,r);if(p(e))return null;n(a(e),"$reverseArray expression must resolve to an array");var u=[];return L(u,e),u.reverse(),u},$size:function(n,t){var r=an(n,t);return a(r)?r.length:void 0},$slice:function(n,t){var r=an(n,t);return sn(r[0],r[1],r[2])},$zip:function(t,r){var e=an(t,r.inputs),i=r.useLongestLength||!1;n(a(e),"'inputs' expression must resolve to an array"),n(u(i),"'useLongestLength' must be a boolean"),a(r.defaults)&&n(m(i),"'useLongestLength' must be set to true to use 'defaults'");for(var o=0,s=0,c=e.length;s<c;s++){var f=e[s];if(p(f))return null;n(a(f),"'inputs' expression values must resolve to an array or null"),o=i?Math.max(o,f.length):Math.min(o||f.length,f.length)}for(var l=[],v=r.defaults||[],h=0;h<o;h++)!function(n){var t=e.map(function(t,r){return p(t[n])?v[r]||null:t[n]});l.push(t)}(h);return l}},Ln={$and:function(n,t){var r=an(n,t);return m(r)&&r.every(m)},$or:function(n,t){var r=an(n,t);return m(r)&&r.some(m)},$not:function(n,t){return!an(n,t[0])}},Bn={$cmp:function(n,t){var r=an(n,t);return r[0]>r[1]?1:r[0]<r[1]?-1:0}};A(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"],function(n){Bn[n]=function(t,r){var e=an(t,r);return Cn[n](e[0],e[1])}});var Yn={$cond:function(t,r){var e=void 0,u=void 0,i=void 0;return a(r)?(n(3===r.length,"Invalid arguments for $cond operator"),e=r[0],u=r[1],i=r[2]):c(r)&&(e=r.if,u=r.then,i=r.else),an(t,e)?an(t,u,null):an(t,i)},$switch:function(t,r){n(r.branches,"Invalid arguments for $switch operator");var e=r.branches.find(function(r){return n(r.case&&r.then,"Invalid arguments for $switch operator"),an(t,r.case)});return e?an(t,e.then):r.default?an(t,r.default):void w("Invalid arguments for $switch operator")},$ifNull:function(t,r){n(a(r)&&2===r.length,"Invalid arguments for $ifNull operator");var e=an(t,r);return null===e[0]||void 0===e[0]?e[1]:e[0]}},Jn={"%Y":["$year",4],"%m":["$month",2],"%d":["$dayOfMonth",2],"%H":["$hour",2],"%M":["$minute",2],"%S":["$second",2],"%L":["$millisecond",3],"%j":["$dayOfYear",3],"%w":["$dayOfWeek",1],"%U":["$week",2],"%%":"%"},zn={$dayOfYear:function(n,t){var r=an(n,t);if(l(r)){var e=new Date(r.getFullYear(),0,0),u=r-e;return Math.round(u/864e5)}},$dayOfMonth:function(n,t){var r=an(n,t);return l(r)?r.getDate():void 0},$dayOfWeek:function(n,t){var r=an(n,t);return l(r)?r.getDay()+1:void 0},$year:function(n,t){var r=an(n,t);return l(r)?r.getFullYear():void 0},$month:function(n,t){var r=an(n,t);return l(r)?r.getMonth()+1:void 0},$week:function(n,t){var r=an(n,t);r=new Date(+r),r.setHours(0,0,0),r.setDate(r.getDate()+4-(r.getDay()||7));var e=new Date(r.getFullYear(),0,1);return Math.floor(((r-e)/864e5+1)/7)},$hour:function(n,t){var r=an(n,t);return l(r)?r.getUTCHours():void 0},$minute:function(n,t){var r=an(n,t);return l(r)?r.getMinutes():void 0},$second:function(n,t){var r=an(n,t);return l(r)?r.getSeconds():void 0},$millisecond:function(n,t){var r=an(n,t);return l(r)?r.getMilliseconds():void 0},$dateToString:function(n,t){for(var r=t.format,e=an(n,t.date),u=r.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g),i=0,o=u.length;i<o;i++){var s=Jn[u[i]],c=s;if(a(s)){var f=this[s[0]],l=s[1];c=Q(f.call(this,n,e),l)}r=r.replace(u[i],c)}return r}},Gn={$literal:function(n,t){return t}},Hn={$setEquals:function(n,t){var r=an(n,t),e=P(r[0]),u=P(r[1]);return e.length===u.length&&e.length===I(e,u).length},$setIntersection:function(n,t){var r=an(n,t);return I(r[0],r[1])},$setDifference:function(n,t){var r=an(n,t);return r[0].filter(y.bind(null,r[1]))},$setUnion:function(n,t){var r=an(n,t);return T(r[0],r[1])},$setIsSubset:function(n,t){var r=an(n,t);return I(r[0],r[1]).length===r[0].length},$anyElementTrue:function(n,t){return an(n,t)[0].some(m)},$allElementsTrue:function(n,t){return an(n,t)[0].every(m)}},Qn={$concat:function(n,t){var r=an(n,t);return[null,void 0].some($.bind(null,r))?null:r.join("")},$indexOfBytes:function(t,r){var e=an(t,r);if(p(e[0]))return null;n(i(e[0]),"$indexOfBytes first operand must resolve to a string"),n(i(e[1]),"$indexOfBytes second operand must resolve to a string");var u=e[0],a=e[1],s=e[2],c=e[3] | ||
;if(n(p(s)||o(s)&&s>=0&&Math.round(s)===s,"$indexOfBytes third operand must resolve to a non-negative integer"),s=s||0,n(p(c)||o(c)&&c>=0&&Math.round(c)===c,"$indexOfBytes fourth operand must resolve to a non-negative integer"),c=c||u.length,s>c)return-1;var f=u.substring(s,c).indexOf(a);return f>-1?f+s:f},$split:function(t,e){var u=an(t,e);return n(i(u[0]),"$split requires an expression that evaluates to a string as a first argument, found: "+r(u[0])),n(i(u[1]),"$split requires an expression that evaluates to a string as a second argument, found: "+r(u[1])),u[0].split(u[1])},$strcasecmp:function(n,t){var r=an(n,t);return r[0]=_(r[0])?"":r[0].toUpperCase(),r[1]=_(r[1])?"":r[1].toUpperCase(),r[0]>r[1]?1:r[0]<r[1]?-1:0},$substr:function(n,t){var r=an(n,t);return i(r[0])?r[1]<0?"":r[2]<0?r[0].substr(r[1]):r[0].substr(r[1],r[2]):""},$toLower:function(n,t){var r=an(n,t);return _(r)?"":r.toLowerCase()},$toUpper:function(n,t){var r=an(n,t);return _(r)?"":r.toUpperCase()}},Vn={$let:function(n,t){var r=t.vars,e=t.in,u={},i=j(r);A(i,function(t){var e=an(n,r[t]),i="$"+t;u[i]=n[i],n[i]=e});var o=an(n,e);return A(i,function(t){var r="$"+t;g(u[r])?delete n[r]:n[r]=u[r]}),o}},Kn=Object.assign({},Fn,Un,Ln,Bn,Yn,zn,Gn,Hn,Qn,Vn),Wn={aggregate:Kn,group:Mn,pipeline:En,projection:An,query:Dn},Xn={key:"_id"},Zn={$$ROOT:function(n,t,r){return r.root},$$CURRENT:function(n,t,r){return n}},nt={$$KEEP:function(n){return n},$$PRUNE:function(){},$$DESCEND:function(n,t,r){if(!O(t,"$cond"))return n;var e=void 0;return A(n,function(u,i){f(u)&&(a(u)?(e=[],A(u,function(n){c(n)&&(n=fn(n,t,r)),p(n)||e.push(n)})):e=fn(u,t,r),p(e)?delete n[i]:n[i]=e)}),n}},tt=j(Zn),rt=j(nt);return{_internal:ln,Aggregator:qn,CollectionMixin:{query:function(n,t){return new Rn(n).find(this.toJSON(),t)},aggregate:function(n){return new qn(n).run(this.toJSON())}},Cursor:Pn,OP_AGGREGATE:On,OP_GROUP:wn,OP_PIPELINE:"pipeline",OP_PROJECTION:jn,OP_QUERY:kn,Query:Rn,VERSION:"1.3.3",addOperators:K,aggregate:z,find:G,remove:H,setup:W}}); | ||
//# sourceMappingURL=dist/mingo.map |
@@ -0,4 +1,5 @@ | ||
import { OP_PIPELINE } from './constants' | ||
import { assert, each, err, inArray, isArray, isEmpty, keys } from './util' | ||
import { Query } from './query' | ||
import { ops, OP_PIPELINE } from './operators/index' | ||
import { ops } from './operators/index' | ||
import { pipelineOperators } from './operators/pipeline.js' | ||
@@ -30,11 +31,8 @@ | ||
let key = keys(operator) | ||
if (key.length === 1 && inArray(ops(OP_PIPELINE), key[0])) { | ||
key = key[0] | ||
if (query instanceof Query) { | ||
collection = pipelineOperators[key].call(query, collection, operator[key]) | ||
} else { | ||
collection = pipelineOperators[key](collection, operator[key]) | ||
} | ||
assert(key.length === 1 && inArray(ops(OP_PIPELINE), key[0]), `Invalid aggregation operator ${key}`) | ||
key = key[0] | ||
if (query && query instanceof Query) { | ||
collection = pipelineOperators[key].call(query, collection, operator[key]) | ||
} else { | ||
err("Invalid aggregation operator '" + key + "'") | ||
collection = pipelineOperators[key](collection, operator[key]) | ||
} | ||
@@ -41,0 +39,0 @@ }) |
import './polyfill' | ||
import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' | ||
import { _internal, setup } from './internal' | ||
@@ -7,5 +8,5 @@ import { Query, find, remove } from './query' | ||
import { Cursor } from './cursor' | ||
import { addOperators, OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './operators/index' | ||
import { addOperators } from './operators/index' | ||
const VERSION = '1.3.2' | ||
const VERSION = '1.3.3' | ||
@@ -12,0 +13,0 @@ // mingo! |
import { | ||
JS_PRIMITIVES, | ||
T_ARRAY, | ||
T_OBJECT, | ||
JS_SIMPLE_TYPES, | ||
OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY | ||
} from './constants' | ||
import { | ||
addMeta, | ||
@@ -31,7 +36,9 @@ assert, | ||
keys, | ||
map, | ||
notInArray, | ||
reduce, | ||
truthy | ||
} from './util' | ||
import { groupOperators } from './operators/group.js' | ||
import { ops, OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './operators/index.js' | ||
import { ops } from './operators/index.js' | ||
import { aggregateOperators } from './operators/aggregation/index.js' | ||
@@ -295,3 +302,3 @@ | ||
// normalized primitives | ||
if (inArray(JS_PRIMITIVES, jsType(expr))) { | ||
if (inArray(JS_SIMPLE_TYPES, jsType(expr))) { | ||
return isRegExp(expr) ? { '$regex': expr } : { '$eq': expr } | ||
@@ -338,4 +345,3 @@ } | ||
*/ | ||
export function computeValue (obj, expr, field, opt = {}) { | ||
opt = opt || {} | ||
export function computeValue (obj, expr, field = null, opt = {}) { | ||
opt.root = opt.root || obj | ||
@@ -383,15 +389,15 @@ | ||
switch (jsType(expr)) { | ||
case 'array': | ||
return expr.map((item) => computeValue(obj, item, null)) | ||
case 'object': | ||
case T_ARRAY: | ||
return expr.map((item) => computeValue(obj, item)) | ||
case T_OBJECT: | ||
let result = {} | ||
each(expr, (val, key, _, halt) => { | ||
each(expr, (val, key) => { | ||
result[key] = computeValue(obj, val, key, opt) | ||
// must run ONLY one aggregate operator per expression | ||
// if so, return result of the computed value | ||
if (inArray(ops(OP_AGGREGATE), key)) { | ||
if (inArray(ops(OP_AGGREGATE, OP_GROUP), key)) { | ||
// there should be only one operator | ||
assert(keys(expr).length === 1, "Invalid aggregation expression '" + JSON.stringify(expr) + "'") | ||
result = result[key] | ||
halt() // break | ||
return false // break | ||
} | ||
@@ -440,7 +446,7 @@ }) | ||
export function stddev (ctx) { | ||
let sum = ctx.data.reduce((acc, n) => acc + n, 0) | ||
let sum = reduce(ctx.data, (acc, n) => acc + n, 0) | ||
let N = ctx.data.length || 1 | ||
let correction = ctx.sampled === true ? 1 : 0 | ||
let avg = sum / (N - correction) | ||
return Math.sqrt(ctx.data.reduce((acc, n) => acc + Math.pow(n - avg, 2), 0) / N) | ||
return Math.sqrt(reduce(ctx.data, (acc, n) => acc + Math.pow(n - avg, 2), 0) / N) | ||
} | ||
@@ -456,3 +462,2 @@ | ||
export function redactObj (obj, expr, opt = {}) { | ||
opt = opt || {} | ||
opt.root = opt.root || obj | ||
@@ -469,3 +474,3 @@ | ||
*/ | ||
export function _internal() { | ||
export function _internal () { | ||
return { | ||
@@ -495,4 +500,5 @@ computeValue, | ||
isUndefined, | ||
keys | ||
keys, | ||
map | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { assert, err, isNil, isNumber, isArray } from '../../util.js' | ||
import { assert, err, isNil, isNumber, isArray, reduce } from '../../util.js' | ||
import { computeValue } from '../../internal.js' | ||
@@ -14,3 +14,3 @@ | ||
$abs (obj, expr) { | ||
let val = computeValue(obj, expr, null) | ||
let val = computeValue(obj, expr) | ||
return (val === null || val === undefined) ? null : Math.abs(val) | ||
@@ -27,4 +27,4 @@ }, | ||
$add (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
return args.reduce((acc, num) => acc + num, 0) | ||
let args = computeValue(obj, expr) | ||
return reduce(args, (acc, num) => acc + num, 0) | ||
}, | ||
@@ -40,3 +40,3 @@ | ||
$ceil (obj, expr) { | ||
let arg = computeValue(obj, expr, null) | ||
let arg = computeValue(obj, expr) | ||
if (isNaN(arg)) return NaN | ||
@@ -56,3 +56,3 @@ if (isNil(arg)) return null | ||
$divide (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return args[0] / args[1] | ||
@@ -69,3 +69,3 @@ }, | ||
$exp (obj, expr) { | ||
let arg = computeValue(obj, expr, null) | ||
let arg = computeValue(obj, expr) | ||
if (isNaN(arg)) return NaN | ||
@@ -85,3 +85,3 @@ if (isNil(arg)) return null | ||
$floor (obj, expr) { | ||
let arg = computeValue(obj, expr, null) | ||
let arg = computeValue(obj, expr) | ||
if (isNaN(arg)) return NaN | ||
@@ -101,3 +101,3 @@ if (isNil(arg)) return null | ||
$ln (obj, expr) { | ||
let arg = computeValue(obj, expr, null) | ||
let arg = computeValue(obj, expr) | ||
if (isNaN(arg)) return NaN | ||
@@ -117,3 +117,3 @@ if (isNil(arg)) return null | ||
$log (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
assert(isArray(args) && args.length === 2, '$log must be a valid expression that resolves to an array of 2 items') | ||
@@ -134,3 +134,3 @@ if (args.some(isNaN)) return NaN | ||
$log10 (obj, expr) { | ||
let arg = computeValue(obj, expr, null) | ||
let arg = computeValue(obj, expr) | ||
if (isNaN(arg)) return NaN | ||
@@ -150,3 +150,3 @@ if (isNil(arg)) return null | ||
$mod (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return args[0] % args[1] | ||
@@ -163,4 +163,4 @@ }, | ||
$multiply (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
return args.reduce((acc, num) => acc * num, 1) | ||
let args = computeValue(obj, expr) | ||
return reduce(args, (acc, num) => acc * num, 1) | ||
}, | ||
@@ -176,5 +176,5 @@ | ||
$pow (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow must be a valid expression that resolves to an array of 2 numbers') | ||
assert(isArray(args) && args.length === 2 && args.every(isNumber), '$pow expression must resolve to an array of 2 numbers') | ||
assert(!(args[0] === 0 && args[1] < 0), '$pow cannot raise 0 to a negative exponent') | ||
@@ -193,6 +193,6 @@ | ||
$sqrt (obj, expr) { | ||
let n = computeValue(obj, expr, null) | ||
let n = computeValue(obj, expr) | ||
if (isNaN(n)) return NaN | ||
if (isNil(n)) return null | ||
assert(isNumber(n) && n > 0, '$sqrt must be a valid expression that resolves to a non-negative number.') | ||
assert(isNumber(n) && n > 0, '$sqrt expression must resolve to non-negative number.') | ||
return Math.sqrt(n) | ||
@@ -209,3 +209,3 @@ }, | ||
$subtract (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return args[0] - args[1] | ||
@@ -222,3 +222,3 @@ }, | ||
$trunc (obj, expr) { | ||
let n = computeValue(obj, expr, null) | ||
let n = computeValue(obj, expr) | ||
if (isNaN(n)) return NaN | ||
@@ -225,0 +225,0 @@ if (isNil(n)) return null |
@@ -1,2 +0,19 @@ | ||
import { assert, each, isNumber, isArray, isBoolean, isNil, truthy } from '../../util.js' | ||
import { | ||
assert, | ||
each, | ||
err, | ||
has, | ||
into, | ||
inArray, | ||
isArray, | ||
isObject, | ||
isNumber, | ||
isBoolean, | ||
isNil, | ||
isUndefined, | ||
keys, | ||
map, | ||
reduce, | ||
truthy | ||
} from '../../util.js' | ||
import { computeValue, slice } from '../../internal.js' | ||
@@ -13,3 +30,3 @@ | ||
$arrayElemAt (obj, expr) { | ||
let arr = computeValue(obj, expr, null) | ||
let arr = computeValue(obj, expr) | ||
assert(isArray(arr) && arr.length === 2, '$arrayElemAt expression must resolve to an array of 2 elements') | ||
@@ -29,2 +46,16 @@ assert(isArray(arr[0]), 'First operand to $arrayElemAt must resolve to an array') | ||
/** | ||
* Converts an array of key value pairs to a document. | ||
*/ | ||
$arrayToObject (obj, expr) { | ||
let arr = computeValue(obj, expr) | ||
assert(isArray(arr), '$arrayToObject expression must resolve to an array') | ||
return reduce(arr, (newObj, val) => { | ||
if (isArray(val) && val.length == 2) newObj[val[0]] = val[1] | ||
else if (isObject(val) && has(val, 'k') && has(val, 'v')) newObj[val.k] = val.v | ||
else err('$arrayToObject expression is invalid.') | ||
return newObj | ||
}, {}) | ||
}, | ||
/** | ||
* Concatenates arrays to return the concatenated array. | ||
@@ -53,7 +84,7 @@ * | ||
$filter (obj, expr) { | ||
let input = computeValue(obj, expr['input'], null) | ||
let input = computeValue(obj, expr.input) | ||
let asVar = expr['as'] | ||
let condExpr = expr['cond'] | ||
assert(isArray(input), "'input' expression for $filter must resolve to an array") | ||
assert(isArray(input), "$filter 'input' expression must resolve to an array") | ||
@@ -64,3 +95,3 @@ return input.filter((o) => { | ||
tempObj['$' + asVar] = o | ||
return computeValue(tempObj, condExpr, null) === true | ||
return computeValue(tempObj, condExpr) === true | ||
}) | ||
@@ -70,3 +101,16 @@ }, | ||
/** | ||
* Searches an array for an occurrence of a specified value and returns the array index of the first occurence. | ||
* Returns a boolean indicating whether a specified value is in an array. | ||
* | ||
* @param {Object} obj | ||
* @param {Array} expr | ||
*/ | ||
$in (obj, expr) { | ||
let val = computeValue(obj, expr[0]) | ||
let arr = computeValue(obj, expr[1]) | ||
assert(isArray(arr), '$in second argument must be an array') | ||
return inArray(arr, val) | ||
}, | ||
/** | ||
* Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. | ||
* If the substring is not found, returns -1. | ||
@@ -79,3 +123,3 @@ * | ||
$indexOfArray (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
if (isNil(args)) return null | ||
@@ -86,3 +130,3 @@ | ||
assert(isArray(arr), 'First operand for $indexOfArray must resolve to an array.') | ||
assert(isArray(arr), '$indexOfArray expression must resolve to an array.') | ||
@@ -110,6 +154,50 @@ let searchValue = args[1] | ||
$isArray (obj, expr) { | ||
return isArray(computeValue(obj, expr, null)) | ||
return isArray(computeValue(obj, expr)) | ||
}, | ||
/** | ||
* Applies a sub-expression to each element of an array and returns the array of resulting values in order. | ||
* | ||
* @param obj | ||
* @param expr | ||
* @returns {Array|*} | ||
*/ | ||
$map (obj, expr) { | ||
let inputExpr = computeValue(obj, expr.input) | ||
assert(isArray(inputExpr), `$map 'input' expression must resolve to an array`) | ||
let asExpr = expr['as'] | ||
let inExpr = expr['in'] | ||
// HACK: add the "as" expression as a value on the object to take advantage of "resolve()" | ||
// which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". | ||
// But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. | ||
let tempKey = '$' + asExpr | ||
// let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) | ||
let original = obj[tempKey] | ||
return map(inputExpr, (item) => { | ||
obj[tempKey] = item | ||
let value = computeValue(obj, inExpr) | ||
// cleanup and restore | ||
if (isUndefined(original)) { | ||
delete obj[tempKey] | ||
} else { | ||
obj[tempKey] = original | ||
} | ||
return value | ||
}) | ||
}, | ||
/** | ||
* Converts a document to an array of documents representing key-value pairs. | ||
*/ | ||
$objectToArray (obj, expr) { | ||
let val = computeValue(obj, expr) | ||
assert(isObject(val), '$objectToArray expression must resolve to an object') | ||
let arr = [] | ||
each(val, (v,k) => arr.push({k,v})) | ||
return arr | ||
}, | ||
/** | ||
* Returns an array whose elements are a generated sequence of numbers. | ||
@@ -122,3 +210,3 @@ * | ||
$range (obj, expr) { | ||
let arr = computeValue(obj, expr, null) | ||
let arr = computeValue(obj, expr) | ||
let start = arr[0] | ||
@@ -139,2 +227,18 @@ let end = arr[1] | ||
/** | ||
* Applies an expression to each element in an array and combines them into a single value. | ||
* | ||
* @param {Object} obj | ||
* @param {*} expr | ||
*/ | ||
$reduce (obj, expr) { | ||
let input = computeValue(obj, expr.input) | ||
let initialValue = computeValue(obj, expr.initialValue) | ||
let inExpr = expr['in'] | ||
if (isNil(input)) return null | ||
assert(isArray(input), "$reduce 'input' expression must resolve to an array") | ||
return reduce(input, (acc, n) => computeValue({ '$value': acc, '$this': n }, inExpr), initialValue) | ||
}, | ||
/** | ||
* Returns an array with the elements in reverse order. | ||
@@ -147,3 +251,3 @@ * | ||
$reverseArray (obj, expr) { | ||
let arr = computeValue(obj, expr, null) | ||
let arr = computeValue(obj, expr) | ||
@@ -154,5 +258,4 @@ if (isNil(arr)) return null | ||
let result = [] | ||
for (let i = arr.length - 1; i > -1; i--) { | ||
result.push(arr[i]) | ||
} | ||
into(result, arr) | ||
result.reverse() | ||
return result | ||
@@ -162,21 +265,2 @@ }, | ||
/** | ||
* Applies an expression to each element in an array and combines them into a single value. | ||
* | ||
* @param {Object} obj | ||
* @param {*} expr | ||
*/ | ||
$reduce (obj, expr) { | ||
let input = computeValue(obj, expr['input'], null) | ||
let initialValue = computeValue(obj, expr['initialValue'], null) | ||
let inExpr = expr['in'] | ||
if (isNil(input)) return null | ||
assert(isArray(input), "'input' expression for $reduce must resolve to an array") | ||
return input.reduce((acc, n) => { | ||
return computeValue({ '$value': acc, '$this': n }, inExpr, null) | ||
}, initialValue) | ||
}, | ||
/** | ||
* Counts and returns the total the number of items in an array. | ||
@@ -188,3 +272,3 @@ * | ||
$size (obj, expr) { | ||
let value = computeValue(obj, expr, null) | ||
let value = computeValue(obj, expr) | ||
return isArray(value) ? value.length : undefined | ||
@@ -201,3 +285,3 @@ }, | ||
$slice (obj, expr) { | ||
let arr = computeValue(obj, expr, null) | ||
let arr = computeValue(obj, expr) | ||
return slice(arr[0], arr[1], arr[2]) | ||
@@ -217,3 +301,3 @@ }, | ||
$zip (obj, expr) { | ||
let inputs = computeValue(obj, expr.inputs, null) | ||
let inputs = computeValue(obj, expr.inputs) | ||
let useLongestLength = expr.useLongestLength || false | ||
@@ -220,0 +304,0 @@ |
@@ -7,2 +7,3 @@ import { computeValue } from '../../internal' | ||
* Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. | ||
* | ||
* @param obj | ||
@@ -13,3 +14,3 @@ * @param expr | ||
$and: (obj, expr) => { | ||
let value = computeValue(obj, expr, null) | ||
let value = computeValue(obj, expr) | ||
return truthy(value) && value.every(truthy) | ||
@@ -20,2 +21,3 @@ }, | ||
* Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. | ||
* | ||
* @param obj | ||
@@ -26,3 +28,3 @@ * @param expr | ||
$or: (obj, expr) => { | ||
let value = computeValue(obj, expr, null) | ||
let value = computeValue(obj, expr) | ||
return truthy(value) && value.some(truthy) | ||
@@ -33,2 +35,3 @@ }, | ||
* Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. | ||
* | ||
* @param obj | ||
@@ -39,4 +42,4 @@ * @param expr | ||
$not: (obj, expr) => { | ||
return !computeValue(obj, expr[0], null) | ||
return !computeValue(obj, expr[0]) | ||
} | ||
} |
@@ -14,3 +14,3 @@ import { each } from '../../util.js' | ||
$cmp (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
if (args[0] > args[1]) return 1 | ||
@@ -24,5 +24,5 @@ if (args[0] < args[1]) return -1 | ||
comparisonOperators[op] = (obj, expr) => { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return simpleOperators[op](args[0], args[1]) | ||
} | ||
}) |
@@ -29,4 +29,4 @@ /** | ||
} | ||
let condition = computeValue(obj, ifExpr, null) | ||
return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr, null) | ||
let condition = computeValue(obj, ifExpr) | ||
return condition ? computeValue(obj, thenExpr, null) : computeValue(obj, elseExpr) | ||
}, | ||
@@ -47,11 +47,11 @@ | ||
assert(branch['case'] && branch['then'], 'Invalid arguments for $switch operator') | ||
return computeValue(obj, branch['case'], null) | ||
return computeValue(obj, branch['case']) | ||
}) | ||
if (validBranch) { | ||
return computeValue(obj, validBranch.then, null) | ||
return computeValue(obj, validBranch.then) | ||
} else if (!expr.default) { | ||
err('Invalid arguments for $switch operator') | ||
} else { | ||
return computeValue(obj, expr.default, null) | ||
return computeValue(obj, expr.default) | ||
} | ||
@@ -70,5 +70,5 @@ }, | ||
assert(isArray(expr) && expr.length === 2, 'Invalid arguments for $ifNull operator') | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return (args[0] === null || args[0] === undefined) ? args[1] : args[0] | ||
} | ||
} |
@@ -27,3 +27,3 @@ | ||
$dayOfYear (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
if (isDate(d)) { | ||
@@ -44,3 +44,3 @@ let start = new Date(d.getFullYear(), 0, 0) | ||
$dayOfMonth (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getDate() : undefined | ||
@@ -55,3 +55,3 @@ }, | ||
$dayOfWeek (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getDay() + 1 : undefined | ||
@@ -66,3 +66,3 @@ }, | ||
$year (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getFullYear() : undefined | ||
@@ -77,3 +77,3 @@ }, | ||
$month (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getMonth() + 1 : undefined | ||
@@ -90,3 +90,3 @@ }, | ||
// source: http://stackoverflow.com/a/6117889/1370481 | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
@@ -111,3 +111,3 @@ // Copy date so don't modify original | ||
$hour (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getUTCHours() : undefined | ||
@@ -122,3 +122,3 @@ }, | ||
$minute (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getMinutes() : undefined | ||
@@ -133,3 +133,3 @@ }, | ||
$second (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getSeconds() : undefined | ||
@@ -144,3 +144,3 @@ }, | ||
$millisecond (obj, expr) { | ||
let d = computeValue(obj, expr, null) | ||
let d = computeValue(obj, expr) | ||
return isDate(d) ? d.getMilliseconds() : undefined | ||
@@ -169,3 +169,3 @@ }, | ||
let fmt = expr['format'] | ||
let date = computeValue(obj, expr['date'], null) | ||
let date = computeValue(obj, expr['date']) | ||
let matches = fmt.match(/(%%|%Y|%m|%d|%H|%M|%S|%L|%j|%w|%U)/g) | ||
@@ -172,0 +172,0 @@ |
@@ -11,3 +11,3 @@ import { union, unique, intersection, notInArray, inArray, truthy } from '../../util.js' | ||
$setEquals (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
let xs = unique(args[0]) | ||
@@ -24,3 +24,3 @@ let ys = unique(args[1]) | ||
$setIntersection (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return intersection(args[0], args[1]) | ||
@@ -35,3 +35,3 @@ }, | ||
$setDifference (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return args[0].filter(notInArray.bind(null, args[1])) | ||
@@ -46,3 +46,3 @@ }, | ||
$setUnion (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return union(args[0], args[1]) | ||
@@ -57,3 +57,3 @@ }, | ||
$setIsSubset (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
return intersection(args[0], args[1]).length === args[0].length | ||
@@ -69,3 +69,3 @@ }, | ||
// mongodb nests the array expression in another | ||
let args = computeValue(obj, expr, null)[0] | ||
let args = computeValue(obj, expr)[0] | ||
return args.some(truthy) | ||
@@ -81,5 +81,5 @@ }, | ||
// mongodb nests the array expression in another | ||
let args = computeValue(obj, expr, null)[0] | ||
let args = computeValue(obj, expr)[0] | ||
return args.every(truthy) | ||
} | ||
} |
@@ -14,3 +14,3 @@ import { assert, err, isString, isNil, isNumber, isEmpty, inArray, getType } from '../../util.js' | ||
$concat (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
// does not allow concatenation with nulls | ||
@@ -32,3 +32,3 @@ if ([null, undefined].some(inArray.bind(null, args))) { | ||
$indexOfBytes (obj, expr) { | ||
let arr = computeValue(obj, expr, null) | ||
let arr = computeValue(obj, expr) | ||
@@ -74,3 +74,3 @@ if (isNil(arr[0])) return null | ||
$split (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
assert(isString(args[0]), '$split requires an expression that evaluates to a string as a first argument, found: ' + getType(args[0])) | ||
@@ -89,3 +89,3 @@ assert(isString(args[1]), '$split requires an expression that evaluates to a string as a second argument, found: ' + getType(args[1])) | ||
$strcasecmp (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
args[0] = isEmpty(args[0]) ? '' : args[0].toUpperCase() | ||
@@ -108,3 +108,3 @@ args[1] = isEmpty(args[1]) ? '' : args[1].toUpperCase() | ||
$substr (obj, expr) { | ||
let args = computeValue(obj, expr, null) | ||
let args = computeValue(obj, expr) | ||
if (isString(args[0])) { | ||
@@ -130,3 +130,3 @@ if (args[1] < 0) { | ||
$toLower (obj, expr) { | ||
let value = computeValue(obj, expr, null) | ||
let value = computeValue(obj, expr) | ||
return isEmpty(value) ? '' : value.toLowerCase() | ||
@@ -143,5 +143,5 @@ }, | ||
$toUpper (obj, expr) { | ||
let value = computeValue(obj, expr, null) | ||
let value = computeValue(obj, expr) | ||
return isEmpty(value) ? '' : value.toUpperCase() | ||
} | ||
} |
@@ -10,35 +10,2 @@ /** | ||
/** | ||
* Applies a sub-expression to each element of an array and returns the array of resulting values in order. | ||
* | ||
* @param obj | ||
* @param expr | ||
* @returns {Array|*} | ||
*/ | ||
$map (obj, expr) { | ||
let inputExpr = computeValue(obj, expr['input'], null) | ||
assert(isArray(inputExpr), 'Input expression for $map must resolve to an array') | ||
let asExpr = expr['as'] | ||
let inExpr = expr['in'] | ||
// HACK: add the "as" expression as a value on the object to take advantage of "resolve()" | ||
// which will reduce to that value when invoked. The reference to the as expression will be prefixed with "$$". | ||
// But since a "$" is stripped of before passing the name to "resolve()" we just need to prepend "$" to the key. | ||
let tempKey = '$' + asExpr | ||
// let's save any value that existed, kinda useless but YOU CAN NEVER BE TOO SURE, CAN YOU :) | ||
let original = obj[tempKey] | ||
return inputExpr.map((item) => { | ||
obj[tempKey] = item | ||
let value = computeValue(obj, inExpr, null) | ||
// cleanup and restore | ||
if (isUndefined(original)) { | ||
delete obj[tempKey] | ||
} else { | ||
obj[tempKey] = original | ||
} | ||
return value | ||
}) | ||
}, | ||
/** | ||
* Defines variables for use within the scope of a sub-expression and returns the result of the sub-expression. | ||
@@ -58,3 +25,3 @@ * | ||
each(varsKeys, (key) => { | ||
let val = computeValue(obj, varsExpr[key], null) | ||
let val = computeValue(obj, varsExpr[key]) | ||
let tempKey = '$' + key | ||
@@ -66,3 +33,3 @@ // set value on object using same technique as in "$map" | ||
let value = computeValue(obj, inExpr, null) | ||
let value = computeValue(obj, inExpr) | ||
@@ -69,0 +36,0 @@ // cleanup and restore |
@@ -27,2 +27,3 @@ import { | ||
notInArray, | ||
reduce, | ||
unique | ||
@@ -63,3 +64,3 @@ } from '../util' | ||
} | ||
return this.$push(collection, expr).filter(isNumber).reduce((acc, n) => acc + n, 0) | ||
return reduce(this.$push(collection, expr).filter(isNumber), (acc, n) => acc + n, 0) | ||
}, | ||
@@ -76,3 +77,3 @@ | ||
let mapped = this.$push(collection, expr) | ||
return mapped.reduce((acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) | ||
return reduce(mapped, (acc, n) => (isNil(acc) || n > acc) ? n : acc, undefined) | ||
}, | ||
@@ -89,3 +90,3 @@ | ||
let mapped = this.$push(collection, expr) | ||
return mapped.reduce((acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) | ||
return reduce(mapped, (acc, n) => (isNil(acc) || n < acc) ? n : acc, undefined) | ||
}, | ||
@@ -102,3 +103,3 @@ | ||
let data = this.$push(collection, expr).filter(isNumber) | ||
let sum = data.reduce((acc, n) => acc + n, 0) | ||
let sum = reduce(data, (acc, n) => acc + n, 0) | ||
return sum / (data.length || 1) | ||
@@ -116,3 +117,3 @@ }, | ||
if (isNil(expr)) return collection | ||
return collection.map((obj) => computeValue(obj, expr, null)) | ||
return map(collection, (obj) => computeValue(obj, expr)) | ||
}, | ||
@@ -119,0 +120,0 @@ |
@@ -1,2 +0,3 @@ | ||
import { assert, each, err, has, isBoolean, keys } from '../util' | ||
import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from '../constants' | ||
import { assert, each, err, has, into, isBoolean, keys, reduce } from '../util' | ||
import { _internal, computeValue, idKey, resolve } from '../internal' | ||
@@ -20,17 +21,6 @@ import { Query } from '../query.js' | ||
/** | ||
* Keys specifying different operator classes | ||
* Returns the operators defined for the given operator classes | ||
*/ | ||
export const OP_AGGREGATE = 'aggregate' | ||
export const OP_GROUP = 'group' | ||
export const OP_PIPELINE = 'pipeline' | ||
export const OP_PROJECTION = 'projection' | ||
export const OP_QUERY = 'query' | ||
/** | ||
* Returns the operators defined for the given operator key | ||
* | ||
* @param {String} opClass The operator class to query. See `Mingo.OP_$XXX` members | ||
*/ | ||
export function ops (opClass) { | ||
return keys(OPERATORS[opClass]) | ||
export function ops () { | ||
return reduce(arguments, (acc, cls) => into(acc, keys(OPERATORS[cls])), []) | ||
} | ||
@@ -49,3 +39,3 @@ | ||
// ensure correct type specified | ||
assert(has(OPERATORS, opClass), "Could not identify operator class '" + opClass + "'") | ||
assert(has(OPERATORS, opClass), `Invalid operator class ${opClass}`) | ||
@@ -56,4 +46,4 @@ let operators = OPERATORS[opClass] | ||
each(newOperators, (fn, op) => { | ||
assert(/^\$\w+$/.test(op), "Invalid operator name '" + op + "'") | ||
assert(!has(operators, op), 'Operator ' + op + ' is already defined for ' + opClass + ' operators') | ||
assert(/^\$\w+$/.test(op), `Invalid operator name ${op}`) | ||
assert(!has(operators, op), `${op} already exists for '${opClass}' operators`) | ||
}) | ||
@@ -60,0 +50,0 @@ |
@@ -0,1 +1,2 @@ | ||
import { OP_GROUP, OP_PROJECTION } from '../constants' | ||
import { | ||
@@ -48,3 +49,3 @@ array, | ||
import { Query } from '../query.js' | ||
import { ops, OP_GROUP, OP_PROJECTION } from './index.js' | ||
import { ops } from './index.js' | ||
import { groupOperators } from './group.js' | ||
@@ -70,30 +71,9 @@ import { projectionOperators } from './projection.js' | ||
obj = clone(obj) | ||
each(newFields, (selector) => { | ||
let subExpr = expr[selector] | ||
let newValue | ||
if (isObject(subExpr)) { | ||
let subKeys = keys(subExpr) | ||
// check for any operators first | ||
let operator = subKeys.filter((k) => { | ||
return k.indexOf('$') === 0 | ||
}) | ||
if (!isEmpty(operator)) { | ||
assert(subKeys.length === 1, 'Can have only one root operator in $addFields') | ||
operator = operator[0] | ||
subExpr = subExpr[operator] | ||
newValue = computeValue(obj, subExpr, operator) | ||
} | ||
} else { | ||
newValue = computeValue(obj, subExpr, null) | ||
} | ||
traverse(obj, selector, (o, key) => { | ||
each(newFields, (field) => { | ||
let subExpr = expr[field] | ||
let newValue = computeValue(obj, subExpr) | ||
traverse(obj, field, (o, key) => { | ||
o[key] = newValue | ||
}, true) | ||
}) | ||
return obj | ||
@@ -110,5 +90,6 @@ }) | ||
*/ | ||
$group (collection, expr) { | ||
$group (collection, expr) { | ||
// lookup key for grouping | ||
let objectId = expr[idKey()] | ||
const ID_KEY = idKey() | ||
let objectId = expr[ID_KEY] | ||
@@ -122,3 +103,3 @@ let partitions = groupBy(collection, (obj) => { | ||
// remove the group key | ||
delete expr[idKey()] | ||
delete expr[ID_KEY] | ||
@@ -130,3 +111,3 @@ each(partitions.keys, (value, i) => { | ||
if (!isUndefined(value)) { | ||
obj[idKey()] = value | ||
obj[ID_KEY] = value | ||
} | ||
@@ -449,3 +430,3 @@ | ||
$sample (collection, expr) { | ||
let size = expr['size'] | ||
let size = expr.size | ||
assert(isNumber(size), '$sample size must be a positive integer') | ||
@@ -490,6 +471,6 @@ | ||
$replaceRoot (collection, expr) { | ||
let newRoot = expr['newRoot'] | ||
let newRoot = expr.newRoot | ||
let result = [] | ||
each(collection, (obj) => { | ||
obj = computeValue(obj, newRoot, null) | ||
obj = computeValue(obj, newRoot) | ||
assert(isObject(obj), '$replaceRoot expression must return a valid JS object') | ||
@@ -543,3 +524,3 @@ result.push(obj) | ||
each(collection, (obj) => { | ||
let key = computeValue(obj, expr.groupBy, null) | ||
let key = computeValue(obj, expr.groupBy) | ||
@@ -571,3 +552,2 @@ if (isNil(key) || key < lower || key >= upper) { | ||
let groupByExpr = expr.groupBy | ||
let granularity = expr.granularity | ||
let bucketCount = expr.buckets | ||
@@ -586,3 +566,3 @@ | ||
let sorted = sortBy(collection, (o) => { | ||
let key = computeValueOptimized(o, groupByExpr, null) | ||
let key = computeValueOptimized(o, groupByExpr) | ||
if (isNil(key)) { | ||
@@ -597,2 +577,3 @@ remaining.push(o) | ||
const ID_KEY = idKey() | ||
let result = [] | ||
@@ -606,3 +587,3 @@ let index = 0 // counter for sorted collection | ||
for (let j = 0; j < approxBucketSize && index < len; j++) { | ||
let key = computeValueOptimized(sorted[index], groupByExpr, null) | ||
let key = computeValueOptimized(sorted[index], groupByExpr) | ||
@@ -618,7 +599,7 @@ if (isNil(key)) key = null | ||
// set the min key boundary if not already present | ||
if (!has(boundaries, 'min')) boundaries['min'] = key | ||
if (!has(boundaries, 'min')) boundaries.min = key | ||
if (result.length > 0) { | ||
let lastBucket = result[result.length - 1] | ||
lastBucket['_id']['max'] = boundaries['min'] | ||
lastBucket[ID_KEY].max = boundaries.min | ||
} | ||
@@ -636,3 +617,3 @@ } | ||
if (result.length > 0) { | ||
result[result.length - 1]['_id']['max'] = computeValueOptimized(sorted[sorted.length - 1], groupByExpr, null) | ||
result[result.length - 1][ID_KEY].max = computeValueOptimized(sorted[sorted.length - 1], groupByExpr) | ||
} | ||
@@ -667,3 +648,3 @@ | ||
let result = {} | ||
each(expr, (val, key, _, halt) => { | ||
each(expr, (val, key) => { | ||
result[key] = accumulate(collection, key, expr[key]) | ||
@@ -676,3 +657,3 @@ // must run ONLY one group operator per expression | ||
assert(keys(expr).length === 1, "Invalid $group expression '" + JSON.stringify(expr) + "'") | ||
halt() // break | ||
return false // break | ||
} | ||
@@ -679,0 +660,0 @@ }) |
/** | ||
* Query and Projection Operators. https://docs.mongodb.com/manual/reference/operator/query/ | ||
*/ | ||
import { | ||
T_ARRAY, | ||
T_BOOL, | ||
T_BOOLEAN, | ||
T_DATE, | ||
T_FUNCTION, | ||
T_NULL, | ||
T_NUMBER, | ||
T_OBJECT, | ||
T_REGEX, | ||
T_REGEXP, | ||
T_STRING, | ||
T_UNDEFINED | ||
} from '../constants' | ||
import { | ||
array, | ||
@@ -11,6 +24,2 @@ assert, | ||
each, | ||
err, | ||
getHash, | ||
getType, | ||
has, | ||
hasMeta, | ||
@@ -29,8 +38,6 @@ inArray, | ||
isObject, | ||
isObjectLike, | ||
isRegExp, | ||
isString, | ||
isUndefined, | ||
keys, | ||
notInArray | ||
keys | ||
} from '../util' | ||
@@ -254,38 +261,36 @@ import { computeValue, resolve, normalize } from '../internal.js' | ||
case 1: | ||
case "double": | ||
case 'double': | ||
return isNumber(a) && (a + '').indexOf('.') !== -1 | ||
case 2: | ||
case "string": | ||
case 5: | ||
case "bindata": | ||
case T_STRING: | ||
return isString(a) | ||
case 3: | ||
case "object": | ||
case T_OBJECT: | ||
return isObject(a) | ||
case 4: | ||
case "array": | ||
case T_ARRAY: | ||
return isArray(a) | ||
case 6: | ||
case "undefined": | ||
case T_UNDEFINED: | ||
return isNil(a) | ||
case 8: | ||
case "bool": | ||
case T_BOOL: | ||
return isBoolean(a) | ||
case 9: | ||
case "date": | ||
case T_DATE: | ||
return isDate(a) | ||
case 10: | ||
case "null": | ||
case T_NULL: | ||
return isNull(a) | ||
case 11: | ||
case "regex": | ||
case T_REGEX: | ||
return isRegExp(a) | ||
case 16: | ||
case "int": | ||
case 'int': | ||
return isNumber(a) && a <= 2147483647 && (a + '').indexOf('.') === -1 | ||
case 18: | ||
case "long": | ||
case 'long': | ||
return isNumber(a) && a > 2147483647 && a <= 9223372036854775807 && (a + '').indexOf('.') === -1 | ||
case 19: | ||
case "decimal": | ||
case 'decimal': | ||
return isNumber(a) | ||
@@ -292,0 +297,0 @@ default: |
@@ -143,3 +143,3 @@ | ||
// Avoid bugs when hasOwnProperty is shadowed | ||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { | ||
if (nextSource.hasOwnProperty(nextKey)) { | ||
to[nextKey] = nextSource[nextKey] | ||
@@ -163,3 +163,3 @@ } | ||
for (var k in o) { | ||
if (Object.prototype.hasOwnProperty.call(o, k)) { | ||
if (o.hasOwnProperty(k)) { | ||
result.push(k) | ||
@@ -180,3 +180,3 @@ } | ||
for (var k in o) { | ||
if (Object.prototype.hasOwnProperty.call(o, k)) { | ||
if (o.hasOwnProperty(k)) { | ||
result.push(o[k]) | ||
@@ -183,0 +183,0 @@ } |
@@ -0,1 +1,2 @@ | ||
import { OP_AGGREGATE, OP_GROUP, OP_PIPELINE, OP_PROJECTION, OP_QUERY } from './constants' | ||
import { | ||
@@ -23,15 +24,8 @@ assert, | ||
isUndefined, | ||
notInArray | ||
notInArray, | ||
reduce | ||
} from './util' | ||
import { computeValue, normalize } from './internal.js' | ||
import { normalize } from './internal.js' | ||
import { Cursor } from './cursor.js' | ||
import { | ||
ops, | ||
OP_AGGREGATE, | ||
OP_GROUP, | ||
OP_PIPELINE, | ||
OP_PROJECTION, | ||
OP_QUERY | ||
} from './operators/index.js' | ||
import { ops } from './operators/index.js' | ||
import { groupOperators } from './operators/group.js' | ||
@@ -120,6 +114,4 @@ import { queryOperators } from './operators/query.js' | ||
remove (collection) { | ||
return collection.reduce((acc, obj) => { | ||
if (!this.test(obj)) { | ||
acc.push(obj) | ||
} | ||
return reduce(collection, (acc, obj) => { | ||
if (!this.test(obj)) acc.push(obj) | ||
return acc | ||
@@ -126,0 +118,0 @@ }, []) |
172
lib/util.js
@@ -5,2 +5,17 @@ /** | ||
import { | ||
T_ARRAY, | ||
T_BOOL, | ||
T_BOOLEAN, | ||
T_DATE, | ||
T_FUNCTION, | ||
T_NULL, | ||
T_NUMBER, | ||
T_OBJECT, | ||
T_REGEX, | ||
T_REGEXP, | ||
T_STRING, | ||
T_UNDEFINED | ||
} from './constants' | ||
export function assert (condition, message) { | ||
@@ -12,34 +27,35 @@ if (falsey(condition)) err(message) | ||
* Deep clone an object | ||
* @param obj | ||
* @returns {*} | ||
*/ | ||
export function clone (arg) { | ||
switch (jsType(arg)) { | ||
case 'array': | ||
return arg.map(clone) | ||
case 'object': | ||
return map(arg, clone) | ||
export function clone (obj) { | ||
switch (jsType(obj)) { | ||
case T_ARRAY: | ||
return obj.map(clone) | ||
case T_OBJECT: | ||
return map(obj, clone) | ||
default: | ||
return arg | ||
return obj | ||
} | ||
} | ||
export const JS_PRIMITIVES = ['null', 'undefined', 'boolean', 'number', 'string', 'date', 'regexp'] | ||
export function getType (v) { | ||
if (v === null) return "Null" | ||
if (v === undefined) return "Undefined" | ||
if (v === null) return 'Null' | ||
if (v === undefined) return 'Undefined' | ||
return v.constructor.name | ||
} | ||
export function jsType (v) { return getType(v).toLowerCase() } | ||
export function isBoolean (v) { return jsType(v) === 'boolean' } | ||
export function isString (v) { return jsType(v) === 'string' } | ||
export function isNumber (v) { return jsType(v) === 'number' } | ||
export function isArray (v) { return jsType(v) === 'array' } | ||
export function isObject (v) { return jsType(v) === 'object' } | ||
export function isBoolean (v) { return jsType(v) === T_BOOLEAN } | ||
export function isString (v) { return jsType(v) === T_STRING } | ||
export function isNumber (v) { return jsType(v) === T_NUMBER } | ||
export function isArray (v) { return jsType(v) === T_ARRAY } | ||
export function isArrayLike (v) { return !isNil(v) && has(v, 'length') } | ||
export function isObject (v) { return jsType(v) === T_OBJECT } | ||
export function isObjectLike (v) { return v === Object(v) } // objects, arrays, functions, date, custom object | ||
export function isDate (v) { return jsType(v) === 'date' } | ||
export function isRegExp (v) { return jsType(v) === 'regexp' } | ||
export function isFunction (v) { return jsType(v) === 'function' } | ||
export function isDate (v) { return jsType(v) === T_DATE } | ||
export function isRegExp (v) { return jsType(v) === T_REGEXP } | ||
export function isFunction (v) { return jsType(v) === T_FUNCTION } | ||
export function isNil (v) { return isNull(v) || isUndefined(v) } | ||
export function isNull (v) { return jsType(v) === 'null' } | ||
export function isUndefined (v) { return jsType(v) === 'undefined' } | ||
export function isNull (v) { return jsType(v) === T_NULL } | ||
export function isUndefined (v) { return jsType(v) === T_UNDEFINED } | ||
export function inArray (arr, item) { return arr.includes(item) } | ||
@@ -54,5 +70,5 @@ export function notInArray (arr, item) { return !arr.includes(item) } | ||
} | ||
// TODO: convert arguments to array | ||
// ensure a value is an array | ||
export function array (x) { return isArray(x) ? x : [x] } | ||
export function has (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop) } | ||
export function has (obj, prop) { return obj.hasOwnProperty(prop) } | ||
export function err (s) { throw new Error(s) } | ||
@@ -63,12 +79,15 @@ export function keys (o) { return Object.keys(o) } | ||
// internal constants | ||
const __MINGO_META = '__mingo__' | ||
export function addMeta (obj, value) { | ||
obj.__mingo__ = Object.assign(obj.__mingo__ || {}, value) | ||
obj[__MINGO_META] = Object.assign(obj[__MINGO_META] || {}, value) | ||
} | ||
export function hasMeta (obj, value) { | ||
return has(obj, '__mingo__') && isObject(value) && isEqual(Object.assign({}, obj.__mingo__, value), obj.__mingo__) | ||
return has(obj, __MINGO_META) && isObject(value) && isEqual(Object.assign({}, obj[__MINGO_META], value), obj[__MINGO_META]) | ||
} | ||
export function dropMeta (obj) { | ||
if (has(obj, '__mingo__')) delete obj.__mingo__ | ||
if (has(obj, __MINGO_META)) delete obj[__MINGO_META] | ||
} | ||
@@ -79,23 +98,12 @@ | ||
* @param {Array|Object} obj An object-like value | ||
* @param {Function} callback The callback to run per item | ||
* @param {Function} fn The callback to run per item | ||
* @param {*} ctx The object to use a context | ||
* @return {void} | ||
*/ | ||
export function each (obj, callback, ctx = null) { | ||
export function each (obj, fn, ctx = null) { | ||
assert(obj === Object(obj), "Cannot iterate over object of type '" + jsType(obj) + "'") | ||
let done = false | ||
let halt = () => { | ||
done = true | ||
err('halt') | ||
} | ||
if (isArray(obj)) { | ||
if (isArrayLike(obj)) { | ||
for (let i = 0, len = obj.length; i < len; i++) { | ||
try { | ||
callback.call(ctx, obj[i], i, obj, halt); | ||
} catch (e) { | ||
assert(done, e.message) | ||
return | ||
} | ||
if (fn.call(ctx, obj[i], i, obj) === false) break | ||
} | ||
@@ -105,8 +113,3 @@ } else { | ||
if (has(obj, k)) { | ||
try { | ||
callback.call(ctx, obj[k], k, obj, halt) | ||
} catch (e) { | ||
assert(done, e.message) | ||
return | ||
} | ||
if (fn.call(ctx, obj[k], k, obj) === false) break | ||
} | ||
@@ -121,22 +124,31 @@ } | ||
* @param {Array|Object} obj An array/object whose values to transform | ||
* @param {Function} callback The transform function | ||
* @param {Function} fn The transform function | ||
* @param {*} ctx The value to use as the "this" context for the transform | ||
* @return {Array|Object} Result object after applying the transform | ||
*/ | ||
export function map (obj, callback, ctx = null) { | ||
export function map (obj, fn, ctx = null) { | ||
if (isArray(obj)) { | ||
return obj.map(callback, ctx) | ||
return obj.map(fn, ctx) | ||
} else if (isObject(obj)) { | ||
let o = {} | ||
let arr = keys(obj) | ||
for (let k, i = 0, len = arr.length; i < len; i++) { | ||
k = arr[i] | ||
o[k] = callback.call(ctx, obj[k], k) | ||
} | ||
each(obj, (v, k) => o[k] = fn.call(ctx, v, k), obj) | ||
return o | ||
} | ||
err('Input must be an Array or Object type') | ||
} | ||
/** | ||
* Reduce any array-like object | ||
* @param collection | ||
* @param fn | ||
* @param accumulator | ||
* @returns {*} | ||
*/ | ||
export function reduce (collection, fn, accumulator) { | ||
if (isArray(collection)) return collection.reduce(fn, accumulator) | ||
// array-like objects | ||
each(collection, (v, k) => accumulator = fn(accumulator, v, k, collection)) | ||
return accumulator | ||
} | ||
/** | ||
* Returns the intersection between two arrays | ||
@@ -160,6 +172,3 @@ * | ||
export function union (xs, ys) { | ||
let arr = [] | ||
into(arr, xs) | ||
into(arr, ys.filter(notInArray.bind(null, xs))) | ||
return arr | ||
return into(into([], xs), ys.filter(notInArray.bind(null, xs))) | ||
} | ||
@@ -202,11 +211,11 @@ | ||
let type = jsType(a) | ||
if (type !== jsType(b) || type === 'function') return false | ||
if (type !== jsType(b) || type === T_FUNCTION) return false | ||
// we treat NaN as the same | ||
if (type === 'number' && isNaN(a) && isNaN(b)) return true | ||
if (type === T_NUMBER && isNaN(a) && isNaN(b)) return true | ||
// leverage toString for Date and RegExp types | ||
if (inArray(['date', 'regexp'], type)) return a.toString() === b.toString() | ||
if (inArray([T_DATE, T_REGEXP], type)) return a.toString() === b.toString() | ||
if (type === 'array') { | ||
if (type === T_ARRAY) { | ||
if (a.length === b.length && a.length === 0) return true | ||
@@ -217,3 +226,3 @@ if (a.length !== b.length) return false | ||
} | ||
} else if ([a, b].every(isObject)) { | ||
} else if (type === T_OBJECT) { | ||
// deep compare objects | ||
@@ -239,4 +248,3 @@ let ka = keys(a) | ||
} else { | ||
// we do not know how to compare unknown types | ||
// so we attempt comparing their hashes | ||
// we do not know how to compare custom types so we guess | ||
return getHash(a) === getHash(b) | ||
@@ -283,19 +291,19 @@ } | ||
switch (type) { | ||
case 'function': | ||
case T_FUNCTION: | ||
return randomString(7) | ||
case 'boolean': | ||
case 'number': | ||
case 'regex': | ||
case T_BOOLEAN: | ||
case T_NUMBER: | ||
case T_REGEXP: | ||
return value.toString() | ||
case 'string': | ||
case T_STRING: | ||
return JSON.stringify(value) | ||
case 'date': | ||
case T_DATE: | ||
return value.toISOString() | ||
case 'null': | ||
case 'undefined': | ||
case T_NULL: | ||
case T_UNDEFINED: | ||
return type | ||
case 'array': | ||
case T_ARRAY: | ||
return '[' + map(value, (v) => `${encode(v)}`) + ']' | ||
default: | ||
let prefix = !isObject(value)? `${getType(value)}|` : '' | ||
let prefix = (type === T_OBJECT)? '' : `${getType(value)}|` | ||
let objKeys = keys(value) | ||
@@ -365,6 +373,3 @@ objKeys.sort() | ||
}) | ||
into(result, sorted) | ||
assert(result.length === collection.length, 'sortBy must retain collection length') | ||
return result | ||
return into(result, sorted) | ||
} | ||
@@ -385,5 +390,3 @@ | ||
} | ||
let lookup = {} | ||
each(collection, (obj) => { | ||
@@ -403,4 +406,2 @@ let key = fn.call(ctx, obj) | ||
}) | ||
assert(result.keys.length === result.groups.length, 'Cardinality must be equal for groups and keys') | ||
return result | ||
@@ -417,2 +418,3 @@ } | ||
Array.prototype.push.apply(target, xs) | ||
return target | ||
} | ||
@@ -419,0 +421,0 @@ |
{ | ||
"name": "mingo", | ||
"version": "1.3.2", | ||
"version": "1.3.3", | ||
"description": "JavaScript implementation of MongoDB query language", | ||
@@ -5,0 +5,0 @@ "main": "dist/mingo.js", |
@@ -1,2 +0,2 @@ | ||
# Mingo | ||
# mingo | ||
JavaScript implementation of MongoDB query language | ||
@@ -3,0 +3,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
426570
36
10977