diff --git a/packages/@jsonql/client/README.md b/packages/@jsonql/client/README.md new file mode 100644 index 0000000000000000000000000000000000000000..845ef4f6f7c4cb9c36cf2ce40e048b4ec7bed00f --- /dev/null +++ b/packages/@jsonql/client/README.md @@ -0,0 +1,30 @@ +# @jsonql/client + +> This is jsonql http client for javascript, previously release as jsonql-client + +## How to use it + +First this version **DOES NOT** distribute with the [Flyio](https://github.com/wendux/fly) module. You have to explicitly import it yourself. +The reason is - we intend to support as many platform as possible, and Fly allow you to do just that, check their +[documentation](https://github.com/wendux/fly) for more information. + +```js +import Fly from 'flyio' +import jsonqlClient from '@jsonql/client' + +const client = jsonqlClient(Fly, config) + +client.then(c => { + c.query.helloWorld() + .then(msg => { + // should be a Hello World message + }) +}) + +``` + +Please consult [jsonql.org](https:jsonql.js.org) for more information. + +--- + +NB + T1S diff --git a/packages/@jsonql/client/core.js b/packages/@jsonql/client/core.js new file mode 100644 index 0000000000000000000000000000000000000000..9933a71392c98f78eaade902eb3e0f2f0fc95075 --- /dev/null +++ b/packages/@jsonql/client/core.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("debug")):"function"==typeof define&&define.amd?define(["debug"],e):(t=t||self).jsonqlClient=e(t.debug)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e="application/vnd.api+json",r={Accept:e,"Content-Type":[e,"charset=utf-8"].join(";")},n=["POST","PUT"],o="continue",i="type",a="optional",u="enumv",c="args",s="checker",f="alias",l="login",p="logout",h={desc:"y"},d="No message";var v="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},g="object"==typeof v&&v&&v.Object===Object&&v,y="object"==typeof self&&self&&self.Object===Object&&self,b=g||y||Function("return this")(),m=b.Symbol;function _(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r=n?t:function(t,e,r){var n=-1,o=t.length;e<0&&(e=-e>o?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n-1;);return r}(n,o),function(t,e){for(var r=t.length;r--&&M(e,t[r],0)>-1;);return r}(n,o)+1).join("")}function rt(t){return void 0===t}var nt="[object Boolean]";var ot="[object Number]";function it(t){return function(t){return"number"==typeof t||P(t)&&q(t)==ot}(t)&&t!=+t}var at="[object String]";function ut(t){return"string"==typeof t||!w(t)&&P(t)&&q(t)==at}function ct(t,e){return function(r){return t(e(r))}}var st=ct(Object.getPrototypeOf,Object),ft="[object Object]",lt=Function.prototype,pt=Object.prototype,ht=lt.toString,dt=pt.hasOwnProperty,vt=ht.call(Object);function gt(t){if(!P(t)||q(t)!=ft)return!1;var e=st(t);if(null===e)return!0;var r=dt.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&ht.call(r)==vt}var yt,bt=function(t,e,r){for(var n=-1,o=Object(t),i=r(t),a=i.length;a--;){var u=i[yt?a:++n];if(!1===e(o[u],u,o))break}return t};var mt="[object Arguments]";function _t(t){return P(t)&&q(t)==mt}var wt=Object.prototype,jt=wt.hasOwnProperty,St=wt.propertyIsEnumerable,Ot=_t(function(){return arguments}())?_t:function(t){return P(t)&&jt.call(t,"callee")&&!St.call(t,"callee")};var Et="object"==typeof exports&&exports&&!exports.nodeType&&exports,kt=Et&&"object"==typeof module&&module&&!module.nodeType&&module,At=kt&&kt.exports===Et?b.Buffer:void 0,Tt=(At?At.isBuffer:void 0)||function(){return!1},xt=9007199254740991,qt=/^(?:0|[1-9]\d*)$/;function Pt(t,e){var r=typeof t;return!!(e=null==e?xt:e)&&("number"==r||"symbol"!=r&&qt.test(t))&&t>-1&&t%1==0&&t-1&&t%1==0&&t<=Ct}var $t={};$t["[object Float32Array]"]=$t["[object Float64Array]"]=$t["[object Int8Array]"]=$t["[object Int16Array]"]=$t["[object Int32Array]"]=$t["[object Uint8Array]"]=$t["[object Uint8ClampedArray]"]=$t["[object Uint16Array]"]=$t["[object Uint32Array]"]=!0,$t["[object Arguments]"]=$t["[object Array]"]=$t["[object ArrayBuffer]"]=$t["[object Boolean]"]=$t["[object DataView]"]=$t["[object Date]"]=$t["[object Error]"]=$t["[object Function]"]=$t["[object Map]"]=$t["[object Number]"]=$t["[object Object]"]=$t["[object RegExp]"]=$t["[object Set]"]=$t["[object String]"]=$t["[object WeakMap]"]=!1;var zt,Ft="object"==typeof exports&&exports&&!exports.nodeType&&exports,It=Ft&&"object"==typeof module&&module&&!module.nodeType&&module,Jt=It&&It.exports===Ft&&g.process,Rt=function(){try{var t=It&&It.require&&It.require("util").types;return t||Jt&&Jt.binding&&Jt.binding("util")}catch(t){}}(),Mt=Rt&&Rt.isTypedArray,Ut=Mt?(zt=Mt,function(t){return zt(t)}):function(t){return P(t)&&Nt(t.length)&&!!$t[q(t)]},Ht=Object.prototype.hasOwnProperty;function Dt(t,e){var r=w(t),n=!r&&Ot(t),o=!r&&!n&&Tt(t),i=!r&&!n&&!o&&Ut(t),a=r||n||o||i,u=a?function(t,e){for(var r=-1,n=Array(t);++r-1},ae.prototype.set=function(t,e){var r=this.__data__,n=oe(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this};var ue,ce=b["__core-js_shared__"],se=(ue=/[^.]+$/.exec(ce&&ce.keys&&ce.keys.IE_PROTO||""))?"Symbol(src)_1."+ue:"";var fe=Function.prototype.toString;function le(t){if(null!=t){try{return fe.call(t)}catch(t){}try{return t+""}catch(t){}}return""}var pe=/^\[object .+?Constructor\]$/,he=Function.prototype,de=Object.prototype,ve=he.toString,ge=de.hasOwnProperty,ye=RegExp("^"+ve.call(ge).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function be(t){return!(!Gt(t)||function(t){return!!se&&se in t}(t))&&(Zt(t)?ye:pe).test(le(t))}function me(t,e){var r=function(t,e){return null==t?void 0:t[e]}(t,e);return be(r)?r:void 0}var _e=me(b,"Map"),we=me(Object,"create");var je="__lodash_hash_undefined__",Se=Object.prototype.hasOwnProperty;var Oe=Object.prototype.hasOwnProperty;var Ee="__lodash_hash_undefined__";function ke(t){var e=-1,r=null==t?0:t.length;for(this.clear();++eu))return!1;var s=i.get(t);if(s&&i.get(e))return s==e;var f=-1,l=!0,p=r&ze?new Ce:void 0;for(i.set(t,e),i.set(e,t);++f0){if(++e>=Sn)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(jn);function An(t,e){return kn(function(t,e,r){return e=wn(void 0===e?t.length-1:e,0),function(){for(var n=arguments,o=-1,i=wn(n.length-e,0),a=Array(i);++o1?e[n-1]:void 0,i=n>2?e[2]:void 0;for(o=Tn.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,e,r){if(!Gt(r))return!1;var n=typeof e;return!!("number"==n?te(r)&&Pt(e,r.length):"string"==n&&e in r)&&ne(r[e],t)}(e[0],e[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++r0))},Wn=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var e=t.replace("array.<","").replace(">","");return e.indexOf("|")?e.split("|"):[e]}return!1},Qn=function(t,e){var r=t.arg;return e.length>1?!r.filter((function(t){return!(e.length>e.filter((function(e){return!Gn(e)(t)})).length)})).length:e.length>e.filter((function(t){return!Yn(r,t)})).length},Xn=function(t,e){if(void 0===e&&(e=null),gt(t)){if(!e)return!0;if(Yn(e))return!e.filter((function(e){var r=t[e.name];return!(e.type.length>e.type.filter((function(t){var e;return!!rt(r)||(!1!==(e=Wn(t))?!Qn({arg:r},e):!Gn(t)(r))})).length)})).length}return!1},Zn=function(t){var e=t.arg,r=t.param,n=[e];return Array.isArray(r.keys)&&r.keys.length&&n.push(r.keys),Xn.apply(null,n)},to=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 406},r.name.get=function(){return"Jsonql406Error"},Object.defineProperties(e,r),e}(Error),eo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 500},r.name.get=function(){return"Jsonql500Error"},Object.defineProperties(e,r),e}(Error),ro=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 401},r.name.get=function(){return"JsonqlAuthorisationError"},Object.defineProperties(e,r),e}(Error),no=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 401},r.name.get=function(){return"JsonqlContractAuthError"},Object.defineProperties(e,r),e}(Error),oo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 500},r.name.get=function(){return"JsonqlResolverAppError"},Object.defineProperties(e,r),e}(Error),io=function(){try{if(window||document)return!0}catch(t){}return!1},ao=function(){try{if(!io()&&v)return!0}catch(t){}return!1};var uo=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.where=function(){return io()?"browser":ao()?"node":"unknown"},e}(Error),co=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 404},r.name.get=function(){return"JsonqlResolverNotFoundError"},Object.defineProperties(e,r),e}(uo),so=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,r),e}(Error),fo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,r),e}(Error),lo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,r),e}(Error),po=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,r),e}(uo),ho=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0},statusCode:{configurable:!0}};return r.name.get=function(){return"JsonqlError"},r.statusCode.get=function(){return-1},Object.defineProperties(e,r),e}(uo),vo=function(t){function e(r,n){t.call(this,n),this.statusCode=r,this.className=e.name}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlServerError"},Object.defineProperties(e,r),e}(Error),go=Object.freeze({Jsonql406Error:to,Jsonql500Error:eo,JsonqlAuthorisationError:ro,JsonqlContractAuthError:no,JsonqlResolverAppError:oo,JsonqlResolverNotFoundError:co,JsonqlEnumError:so,JsonqlTypeError:fo,JsonqlCheckerError:lo,JsonqlValidationError:po,JsonqlError:ho,JsonqlServerError:vo}),yo=ho,bo=function(t,e){return!!Object.keys(t).filter((function(t){return e===t})).length};function mo(t){if(bo(t,"error")){var e=t.error,r=e.className,n=e.name,o=r||n,i=e.message||d,a=e.detail||e;if(o&&go[o])throw new go[r](i,a);throw new yo(i,a)}return t}function _o(t){if(Array.isArray(t))throw new po("",t);var e=t.message||d,r=t.detail||t;switch(!0){case t instanceof to:throw new to(e,r);case t instanceof eo:throw new eo(e,r);case t instanceof ro:throw new ro(e,r);case t instanceof no:throw new no(e,r);case t instanceof oo:throw new oo(e,r);case t instanceof co:throw new co(e,r);case t instanceof so:throw new so(e,r);case t instanceof fo:throw new fo(e,r);case t instanceof lo:throw new lo(e,r);case t instanceof po:throw new po(e,r);case t instanceof vo:throw new vo(e,r);default:throw new ho(e,r)}}function wo(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];try{window&&window.console&&Reflect.apply(console.log,console,t)}catch(t){}}var jo=function(t,e){var r;switch(!0){case"object"===t:return!Zn(e);case"array"===t:return!Yn(e.arg);case!1!==(r=Wn(t)):return!Qn(e,r);default:return!Gn(t)(e.arg)}},So=function(t,e){return rt(t)?!0!==e.optional||rt(e.defaultvalue)?null:e.defaultvalue:t},Oo=function(t,e,r){var n;void 0===r&&(r=!1);var o=function(t,e){if(!Yn(e))throw new ho("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===e.length)return[];if(!Yn(t))throw new ho("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==e.length:return wo(1),t.map((function(t,r){return{arg:t,index:r,param:e[r]}}));case!0===e[0].variable:wo(2);var r=e[0].type;return t.map((function(t,n){return{arg:t,index:n,param:e[n]||{type:r,name:"_"}}}));case t.lengthe.length:wo(4);var n=e.length,o=["any"];return t.map((function(t,r){var i=r>=n||!!e[r].optional,a=e[r]||{type:o,name:"_"+r};return{arg:i?So(t,a):t,index:r,param:a,optional:i}}));default:throw wo(5),new ho("Could not understand your arguments and parameter structure!",{args:t,params:e})}}(t,e),i=o.filter((function(t){return!0===t.optional||!0===t.param.optional?function(t){var e=t.arg,r=t.param;return!!Fn(e)&&!(r.type.length>r.type.filter((function(e){return jo(e,t)})).length)}(t):!(t.param.type.length>t.param.type.filter((function(e){return jo(e,t)})).length)}));return r?((n={}).error=i,n.data=o.map((function(t){return t.arg})),n):i},Eo=function(t,e){var r,n=Object.keys(t);return r=e,!!n.filter((function(t){return t===r})).length},ko=function(t){return!Fn(t)};function Ao(t,e){var r=zn(e,(function(t,e){return!t[Kn]}));return Ar(r,{})?t:function(t,e){var r={};return e=Zr(e),re(t,(function(t,n,o){en(r,e(t,n,o),t)})),r}(t,(function(t,e){return function(t,e,r){var n;return r(t,(function(t,r,o){if(e(t,r,o))return n=r,!1})),n}(r,Zr((function(t){return t.alias===e})),re)||e}))}function To(t,e){return qn(e,(function(e,r){var n,o;return rt(t[r])||!0===e[Hn]&&ko(t[r])?xn({},e,((n={})[Vn]=!0,n)):((o={})[Ln]=t[r],o[Un]=e[Un],o[Hn]=e[Hn]||!1,o[Dn]=e[Dn]||!1,o[Bn]=e[Bn]||!1,o)}))}function xo(t,e){var r=function(t,e){var r=Ao(t,e);return{pristineValues:qn(zn(e,(function(t,e){return Eo(r,e)})),(function(t){return t.args})),checkAgainstAppProps:zn(e,(function(t,e){return!Eo(r,e)})),config:r}}(t,e),n=r.config,o=r.pristineValues;return[To(n,r.checkAgainstAppProps),o]}var qo=function(t){return Yn(t)?t:[t]};var Po=function(t,e){return!Yn(e)||function(t,e){return!!t.filter((function(t){return t===e})).length}(e,t)},Co=function(t,e){try{return!!Zt(e)&&e.apply(null,[t])}catch(t){return!1}};function No(t){return function(e,r){if(e[Vn])return e[Ln];var n=function(t,e){var r,n=[[t[Ln]],[(r={},r[Un]=qo(t[Un]),r[Hn]=t[Hn],r)]];return Reflect.apply(e,null,n)}(e,t);if(n.length)throw wo("runValidationAction",r,e),new fo(r,n);if(!1!==e[Dn]&&!Po(e[Ln],e[Dn]))throw wo(Dn,e[Dn]),new so(r);if(!1!==e[Bn]&&!Co(e[Ln],e[Bn]))throw wo(Bn,e[Bn]),new lo(r);return e[Ln]}}function $o(t,e){var r=t[0],n=t[1],o=qn(r,No(e));return xn(o,n)}var zo=function(t,e){return Promise.resolve(xo(t,e))};function Fo(t,e,r,n,o,l){void 0===r&&(r=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===l&&(l=!1);var p={};return p[c]=t,p[i]=e,!0===r&&(p[a]=!0),Yn(n)&&(p[u]=n),Zt(o)&&(p[s]=o),ut(l)&&(p[f]=l),p}var Io=Jn,Jo=Yn,Ro=function(t,e,r){return void 0===r&&(r=!1),new Promise((function(n,o){var i=Oo(t,e,r);return r?i.error.length?o(i.error):n(i.data):i.length?o(i):n([])}))},Mo=function(t,e,r){void 0===r&&(r={});var n=r[a],o=r[u],i=r[s],c=r[f];return Fo.apply(null,[t,e,n,o,i,c])},Uo=function(t){return function(e,r,n){return void 0===n&&(n={}),function(t,e,r,n){return void 0===t&&(t={}),zo(t,e).then((function(t){return $o(t,n)})).then((function(t){return xn({},t,r)}))}(e,r,n,t)}}(Oo),Ho=function(t){return function(e,r,n){return void 0===n&&(n={}),function(t,e,r,n){return void 0===t&&(t={}),xn($o(xo(t,e),n),r)}(e,r,n,t)}}(Oo),Do="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var Lo=Object.assign?Object.assign:function(t,e,r,n){for(var o=arguments,i=1;i=0;e--){var r=pi().key(e);t(hi(r),r)}},remove:function(t){return pi().removeItem(t)},clearAll:function(){return pi().clear()}};function pi(){return fi.localStorage}function hi(t){return pi().getItem(t)}var di=Go.trim,vi={name:"cookieStorage",read:function(t){if(!t||!mi(t))return null;var e="(?:^|.*;\\s*)"+escape(t).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";return unescape(gi.cookie.replace(new RegExp(e),"$1"))},write:function(t,e){if(!t)return;gi.cookie=escape(t)+"="+escape(e)+"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"},each:yi,remove:bi,clearAll:function(){yi((function(t,e){bi(e)}))}},gi=Go.Global.document;function yi(t){for(var e=gi.cookie.split(/; ?/g),r=e.length-1;r>=0;r--)if(di(e[r])){var n=e[r].split("="),o=unescape(n[0]);t(unescape(n[1]),o)}}function bi(t){t&&mi(t)&&(gi.cookie=escape(t)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/")}function mi(t){return new RegExp("(?:^|;\\s*)"+escape(t).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(gi.cookie)}var _i=function(){var t={};return{defaults:function(e,r){t=r},get:function(e,r){var n=e();return void 0!==n?n:t[r]}}};var wi="expire_mixin",ji=function(){var t=this.createStore(this.storage,null,this._namespacePrefix+wi);return{set:function(e,r,n,o){this.hasNamespace(wi)||t.set(r,o);return e()},get:function(t,r){this.hasNamespace(wi)||e.call(this,r);return t()},remove:function(e,r){this.hasNamespace(wi)||t.remove(r);return e()},getExpiration:function(e,r){return t.get(r)},removeExpiredKeys:function(t){var r=[];this.each((function(t,e){r.push(e)}));for(var n=0;n>>8,r[2*n+1]=a%256}return r},decompressFromUint8Array:function(e){if(null==e)return i.decompress(e);for(var r=new Array(e.length/2),n=0,o=r.length;n>=1}else{for(o=1,n=0;n>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[f]}else for(o=a[f],n=0;n>=1;0==--l&&(l=Math.pow(2,h),h++),a[s]=p++,f=String(c)}if(""!==f){if(Object.prototype.hasOwnProperty.call(u,f)){if(f.charCodeAt(0)<256){for(n=0;n>=1}else{for(o=1,n=0;n>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[f]}else for(o=a[f],n=0;n>=1;0==--l&&(l=Math.pow(2,h),h++)}for(o=2,n=0;n>=1;for(;;){if(v<<=1,g==e-1){d.push(r(v));break}g++}return d.join("")},decompress:function(t){return null==t?"":""==t?null:i._decompress(t.length,32768,(function(e){return t.charCodeAt(e)}))},_decompress:function(e,r,n){var o,i,a,u,c,s,f,l=[],p=4,h=4,d=3,v="",g=[],y={val:n(0),position:r,index:1};for(o=0;o<3;o+=1)l[o]=o;for(a=0,c=Math.pow(2,2),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;switch(a){case 0:for(a=0,c=Math.pow(2,8),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;f=t(a);break;case 1:for(a=0,c=Math.pow(2,16),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;f=t(a);break;case 2:return""}for(l[3]=f,i=f,g.push(f);;){if(y.index>e)return"";for(a=0,c=Math.pow(2,d),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;switch(f=a){case 0:for(a=0,c=Math.pow(2,8),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;l[h++]=t(a),f=h-1,p--;break;case 1:for(a=0,c=Math.pow(2,16),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;l[h++]=t(a),f=h-1,p--;break;case 2:return g.join("")}if(0==p&&(p=Math.pow(2,d),d++),l[f])v=l[f];else{if(f!==h)return null;v=i+i.charAt(0)}g.push(v),l[h++]=i+v.charAt(0),i=v,0==--p&&(p=Math.pow(2,d),d++)}}};return i}();null!=t&&(t.exports=e)}));var qi=[li,vi],Pi=[_i,ji,Ai,function(){return{get:function(t,e){var r=t(e);if(!r)return r;var n=xi.decompress(r);return null==n?r:this._deserialize(n)},set:function(t,e,r){var n=xi.compress(this._serialize(r));t(e,n)}}}],Ci=ui.createStore(qi,Pi),Ni=Go.Global;function $i(){return Ni.sessionStorage}function zi(t){return $i().getItem(t)}var Fi=[{name:"sessionStorage",read:zi,write:function(t,e){return $i().setItem(t,e)},each:function(t){for(var e=$i().length-1;e>=0;e--){var r=$i().key(e);t(zi(r),r)}},remove:function(t){return $i().removeItem(t)},clearAll:function(){return $i().clear()}},vi],Ii=[_i,ji],Ji=ui.createStore(Fi,Ii),Ri=Ci,Mi=Ji,Ui=Array.isArray,Hi=void 0!==v?v:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},Di="object"==typeof Hi&&Hi&&Hi.Object===Object&&Hi,Li="object"==typeof self&&self&&self.Object===Object&&self,Bi=(Di||Li||Function("return this")()).Symbol,Ki=Object.prototype,Vi=Ki.hasOwnProperty,Gi=Ki.toString,Yi=Bi?Bi.toStringTag:void 0;var Wi=Object.prototype.toString;var Qi="[object Null]",Xi="[object Undefined]",Zi=Bi?Bi.toStringTag:void 0;function ta(t){return null==t?void 0===t?Xi:Qi:Zi&&Zi in Object(t)?function(t){var e=Vi.call(t,Yi),r=t[Yi];try{t[Yi]=void 0;var n=!0}catch(t){}var o=Gi.call(t);return n&&(e?t[Yi]=r:delete t[Yi]),o}(t):function(t){return Wi.call(t)}(t)}var ea=function(t,e){return function(r){return t(e(r))}}(Object.getPrototypeOf,Object);function ra(t){return null!=t&&"object"==typeof t}var na="[object Object]",oa=Function.prototype,ia=Object.prototype,aa=oa.toString,ua=ia.hasOwnProperty,ca=aa.call(Object);var sa=Bi?Bi.prototype:void 0,fa=(sa&&sa.toString,"[object String]");function la(t){return"string"==typeof t||!Ui(t)&&ra(t)&&ta(t)==fa}var pa=function(t,e){return!!t.filter((function(t){return t===e})).length},ha=function(t,e){var r=Object.keys(t);return pa(r,e)},da=function(t){void 0===t&&(t=!1);var e=Date.now();return t?Math.floor(e/1e3):e},va="query",ga="mutation",ya="socket",ba="payload",ma="condition",_a=function(){try{if(window||document)return!0}catch(t){}return!1},wa=function(){try{if(!_a()&&Hi)return!0}catch(t){}return!1};var ja=function(t){function e(){for(var r=arguments,n=[],o=arguments.length;o--;)n[o]=r[o];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,r),e}(function(t){function e(){for(var e=arguments,r=[],n=arguments.length;n--;)r[n]=e[n];t.apply(this,r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.where=function(){return _a()?"browser":wa()?"node":"unknown"},e}(Error));var Sa=function(t){var e;return(e={}).args=t,e};var Oa=function(t){return ha(t,"data")&&!ha(t,"error")?t.data:t},Ea=function(t){return function(t){if(!ra(t)||ta(t)!=na)return!1;var e=ea(t);if(null===e)return!0;var r=ua.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&aa.call(r)==ca}(t)&&(ha(t,va)||ha(t,ga)||ha(t,ya))},ka=function(t,e){return void 0===e&&(e={}),Ea(e)?Promise.resolve(e):t.getContract()},Aa="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function Ta(t){this.message=t}Ta.prototype=new Error,Ta.prototype.name="InvalidCharacterError";var xa="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new Ta("'atob' failed: The string to be decoded is not correctly encoded.");for(var r,n,o=0,i=0,a="";n=e.charAt(i++);~n&&(r=o%4?64*r+n:n,o++%4)?a+=String.fromCharCode(255&r>>(-2*o&6)):0)n=Aa.indexOf(n);return a};var qa=function(t){var e=t.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(xa(t).replace(/(.)/g,(function(t,e){var r=e.charCodeAt(0).toString(16).toUpperCase();return r.length<2&&(r="0"+r),"%"+r})))}(e)}catch(t){return xa(e)}};function Pa(t){this.message=t}Pa.prototype=new Error,Pa.prototype.name="InvalidTokenError";var Ca=function(t,e){if("string"!=typeof t)throw new Pa("Invalid token specified");var r=!0===(e=e||{}).header?0:1;try{return JSON.parse(qa(t.split(".")[r]))}catch(t){throw new Pa("Invalid token specified: "+t.message)}},Na=Pa;Ca.InvalidTokenError=Na;var $a,za,Fa,Ia,Ja,Ra,Ma,Ua,Ha,Da,La,Ba=function(t){void 0===t&&(t=!1);var e=Date.now();return t?Math.floor(e/1e3):e},Ka=v.performance||{};Ka.now||Ka.mozNow||Ka.msNow||Ka.oNow||Ka.webkitNow,$a="koa",void 0===(za="jsonql-utils")&&(za="jsonql"),t(za).extend($a);function Va(t){if(Io(t))return function(t){var e=t.iat||Ba();if(t.exp&&e>=t.exp){var r=new Date(t.exp).toISOString();throw new ho("Token has expired on "+r,t)}return t}(Ca(t));throw new ho("Token must be a string!")}Mo("HS256",["string"]),Mo(!1,["boolean","number","string"],((Fa={})[f]="exp",Fa[a]=!0,Fa)),Mo(!1,["boolean","number","string"],((Ia={})[f]="nbf",Ia[a]=!0,Ia)),Mo(!1,["boolean","string"],((Ja={})[f]="iss",Ja[a]=!0,Ja)),Mo(!1,["boolean","string"],((Ra={})[f]="sub",Ra[a]=!0,Ra)),Mo(!1,["boolean","string"],((Ma={})[f]="iss",Ma[a]=!0,Ma)),Mo(!1,["boolean"],((Ua={})[a]=!0,Ua)),Mo(!1,["boolean","string"],((Ha={})[a]=!0,Ha)),Mo(!1,["boolean","string"],((Da={})[a]=!0,Da)),Mo(!1,["boolean"],((La={})[a]=!0,La));var Ga=n[0],Ya=n[1],Wa=function(t){!function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];try{window&&window.console&&Reflect.apply(console.log,null,t)}catch(t){}}(t),this.fly=t.Fly?new t.Fly:new Fly,this.opts=t,this.extraHeader={},this.extraParams={},this.reqInterceptor(),this.resInterceptor()},Qa={headers:{configurable:!0}};Qa.headers.set=function(t){this.extraHeader=t},Wa.prototype.request=function(t,e,r){var n;void 0===e&&(e={}),void 0===r&&(r={}),this.headers=r;var o=xn({},{_cb:da()},this.extraParams);if(this.opts.enableJsonp){var i=function(t){return Object.keys(t)[0]}(t);o=xn({},o,((n={}).jsonqlJsonpCallback=i,n)),t=t[i]}return this.fly.request(this.jsonqlEndpoint,t,xn({},{method:Ga,params:o},e))},Wa.prototype.reqInterceptor=function(){var t=this;this.fly.interceptors.request.use((function(e){var r=t.getHeaders();for(var n in t.log("request interceptor call",r),r)e.headers[n]=r[n];return e}))},Wa.prototype.processJsonp=function(t){return Oa(t)},Wa.prototype.resInterceptor=function(){var t=this,e=this,r=e.opts.enableJsonp;this.fly.interceptors.response.use((function(n){t.log("response interceptor call"),e.cleanUp();var o=Io(n.data)?JSON.parse(n.data):n.data;return r?e.processJsonp(o):Oa(o)}),(function(t){throw e.cleanUp(),console.error(t),new vo("Server side error",t)}))},Wa.prototype.getHeaders=function(){return this.opts.enableAuth?xn({},r,this.getAuthHeader(),this.extraHeader):xn({},r,this.extraHeader)},Wa.prototype.cleanUp=function(){this.extraHeader={},this.extraParams={}},Wa.prototype.get=function(){var t=this;return this.opts.showContractDesc&&(this.extraParams=xn({},this.extraParams,h)),this.request({},{method:"GET"},this.contractHeader).then(mo).then((function(e){return t.log("get contract result",e),e.cache&&e.contract?e.contract:e}))},Wa.prototype.query=function(t,e){return void 0===e&&(e=[]),this.request(function(t,e,r){var n;if(void 0===e&&(e=[]),void 0===r&&(r=!1),la(t)&&Ui(e)){var o=Sa(e);return!0===r?o:((n={})[t]=o,n)}throw new ja("[createQuery] expect resolverName to be string and args to be array!",{resolverName:t,args:e})}(t,e)).then(mo)},Wa.prototype.mutation=function(t,e,r){return void 0===e&&(e={}),void 0===r&&(r={}),this.request(function(t,e,r,n){var o;void 0===r&&(r={}),void 0===n&&(n=!1);var i={};if(i[ba]=e,i[ma]=r,!0===n)return i;if(la(t))return(o={})[t]=i,o;throw new ja("[createMutation] expect resolverName to be string!",{resolverName:t,payload:e,condition:r})}(t,e,r),{method:Ya}).then(mo)},Object.defineProperties(Wa.prototype,Qa);var Xa=function(t){function e(e,r){void 0===r&&(r=null),r&&(e.Fly=r),t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={storeIt:{configurable:!0},jsonqlEndpoint:{configurable:!0},jsonqlContract:{configurable:!0},jsonqlToken:{configurable:!0},jsonqlUserdata:{configurable:!0}};return r.storeIt.set=function(t){throw console.info("storeIt",t),Jo(t)&&t.length>=2&&Reflect.apply(Ri.set,Ri,t),new po("Expect argument to be array and least 2 items!")},r.jsonqlEndpoint.set=function(t){var e=Ri.get("endpoint")||[];pa(e,t)||(e.push(t),this.storeId=["endpoint",e],this.endpointIndex=e.length-1)},r.jsonqlContract.set=function(t){var e=this.opts.storageKey,r=[e],n=t[0],o=t[1],i=Ri.get(e)||[];i[this.endpointIndex||0]=n,r.push(i),o&&r.push(o),this.opts.keepContract&&(this.storeIt=r)},r.jsonqlToken.set=function(t){var e="credential",r=localStorage.get(e)||[];if(!pa(r,t)){var n=r.length-1;r[n]=t,this[e+"Index"]=n;var o=[e,r];if(this.opts.tokenExpired){var i=parseFloat(this.opts.tokenExpired);if(!isNaN(i)&&i>0){var a=da();o.push(a+parseFloat(i))}}return this.storeIt=o,this.jsonqlUserdata=this.decoder(t),t}return!1},r.jsonqlUserdata.set=function(t){var e=["userdata",t];return t.exp&&e.push(t.exp),Reflect.apply(Ri.set,Ri,e)},r.jsonqlEndpoint.get=function(){var t=Ri.get("endpoint");if(!t){var e=this.opts,r=[e.hostname,e.jsonqlPath].join("/");return this.jsonqlEndpoint=r,r}return t[this.endpointIndex]},r.jsonqlContract.get=function(){var t=this.opts.storageKey;return(Ri.get(t)||[])[this.endpointIndex]||!1},r.jsonqlToken.get=function(){var t="credential",e=localStorage.get(t);return!!e&&e[this[t+"Index"]]},r.jsonqlUserdata.get=function(){return Mi.get("userdata")},e.prototype.log=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];!0===this.opts.debugOn&&Reflect.apply(console.info,console,t)},Object.defineProperties(e.prototype,r),e}(function(t){function e(e){t.call(this,e),e.enableAuth&&e.useJwt&&(this.setDecoder=Va)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={userdata:{configurable:!0},rawAuthToken:{configurable:!0},setDecoder:{configurable:!0}};return r.userdata.get=function(){return this.jsonqlUserdata},r.rawAuthToken.get=function(){return this.jsonqlToken},r.setDecoder.set=function(t){"function"==typeof t&&(this.decoder=t)},e.prototype.storeToken=function(t){return this.jsonqlToken=t},e.prototype.decoder=function(t){return t},e.prototype.getAuthHeader=function(){var t,e=this.rawAuthToken;return e?((t={})[this.opts.AUTH_HEADER]="Bearer "+e,t):{}},Object.defineProperties(e.prototype,r),e}(function(t){function e(e){t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={contractHeader:{configurable:!0}};return e.prototype.getContract=function(){var t=this.readContract();if(this.log("getContract first call",t),t&&Array.isArray(t)){var e=t[this.endpointIndex||0];if(e)return Promise.resolve(e)}return this.get().then(this.storeContract.bind(this))},r.contractHeader.get=function(){var t={};return!1!==this.opts.contractKey&&(t[this.opts.contractKeyName]=this.opts.contractKey),t},e.prototype.storeContract=function(t){if(!Ea(t))throw new po("Contract is malformed!");var e=[t];if(this.opts.contractExpired){var r=parseFloat(this.opts.contractExpired);!isNaN(r)&&r>0&&e.push(r)}return this.jsonqlContract=e,this.log("storeContract return result",t),t},e.prototype.readContract=function(){return Ea(this.opts.contract)?this.opts.contract:Ri.get(this.opts.storageKey)},Object.defineProperties(e.prototype,r),e}(Wa))),Za=function(t,e,r,n){return function(){for(var r=[],o=arguments.length;o--;)r[o]=arguments[o];var i=n.auth[e].params,a=i.map((function(t,e){return r[e]})),u=r[i.length]||{};return Ro(r,i).then((function(){return t.query.apply(t,[e,a,u])})).catch(_o)}};var tu=function(t,e,r,n){var i=function(t,e,r,n){var i={query:{},mutation:{}},a=function(e){i.query[e]=function(){for(var r=[],o=arguments.length;o--;)r[o]=arguments[o];var i=n.query[e].params,a=i.map((function(t,e){return r[e]})),u=r[i.length]||{};return Ro(a,i).then((function(){return t.query.apply(t,[e,a,u])})).catch(_o)}};for(var u in n.query)a(u);var c=function(e){i.mutation[e]=function(r,o,i){void 0===i&&(i={});var a=[r,o],u=n.mutation[e].params;return Ro(a,u).then((function(){return t.mutation.apply(t,[e,r,o,i])})).catch(_o)}};for(var s in n.mutation)c(s);if(r.enableAuth&&n.auth){i.auth={};var f=r.loginHandlerName,h=r.logoutHandlerName;n.auth[f]&&(i.auth[f]=function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];var a=Za(t,f,r,n);return a.apply(null,o).then(t.postLoginAction).then((function(t){return e.$trigger(l,t),t}))}),n.auth[h]?i.auth[h]=function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];var a=Za(t,h,r,n);return a.apply(null,o).then(t.postLogoutAction).then((function(t){return e.$trigger(p,t),t}))}:i.auth[h]=function(){t.postLogoutAction(o),e.$trigger(p,o)}}return i}(t,n,e,r);return e.enableAuth&&(i.userdata=function(){return t.userdata}),i.getToken=function(){return t.rawAuthToken},e.exposeContract&&(i.getContract=function(){return t.get()}),i.eventEmitter=n,i.version="0.1.0",i},eu={contract:!1,MUTATION_ARGS:["name","payload","conditions"],CONTENT_TYPE:e,BEARER:"Bearer",AUTH_HEADER:"Authorization"},ru={hostname:Mo([window.location.protocol,window.location.host].join("//"),["string"]),jsonqlPath:Mo("jsonql",["string"]),loginHandlerName:Mo(l,["string"]),logoutHandlerName:Mo(p,["string"]),enableJsonp:Mo(!1,["boolean"]),enableAuth:Mo(!1,["boolean"]),useJwt:Mo(!0,["boolean"]),useLocalstorage:Mo(!0,["boolean"]),storageKey:Mo("storageKey",["string"]),authKey:Mo("authKey",["string"]),contractExpired:Mo(0,["number"]),keepContract:Mo(!0,["boolean"]),exposeContract:Mo(!1,["boolean"]),showContractDesc:Mo(!1,["boolean"]),contractKey:Mo(!1,["boolean"]),contractKeyName:Mo("X-JSONQL-CV-KEY",["string"]),enableTimeout:Mo(!1,["boolean"]),timeout:Mo(5e3,["number"]),returnInstance:Mo(!1,["boolean"]),allowReturnRawToken:Mo(!1,["boolean"]),debugOn:Mo(!1,["boolean"])};function nu(t,e,r){return void 0===e&&(e={}),void 0===r&&(r=null),function(t){var e=t.contract;return Uo(t,ru,eu).then((function(t){return t.contract=e,t}))}(e).then((function(t){return{baseClient:new Xa(t,r),opts:t}})).then((function(e){var r=e.baseClient,n=e.opts;return ka(r,n.contract).then((function(e){return tu(r,n,e,t)}))}))}var ou=new WeakMap,iu=new WeakMap;var au=function(){this.__suspend__=null,this.queueStore=new Set},uu={$suspend:{configurable:!0},$queues:{configurable:!0}};uu.$suspend.set=function(t){var e=this;if("boolean"!=typeof t)throw new Error("$suspend only accept Boolean value!");var r=this.__suspend__;this.__suspend__=t,this.logger("($suspend)","Change from "+r+" --\x3e "+t),!0===r&&!1===t&&setTimeout((function(){e.release()}),1)},au.prototype.$queue=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];return!0===this.__suspend__&&(this.logger("($queue)","added to $queue",t),this.queueStore.add(t)),this.__suspend__},uu.$queues.get=function(){var t=this.queueStore.size;return this.logger("($queues)","size: "+t),t>0?Array.from(this.queueStore):[]},au.prototype.release=function(){var t=this,e=this.queueStore.size;if(this.logger("(release)","Release was called "+e),e>0){var r=Array.from(this.queueStore);this.queueStore.clear(),this.logger("queue",r),r.forEach((function(e){t.logger(e),Reflect.apply(t.$trigger,t,e)})),this.logger("Release size "+this.queueStore.size)}},Object.defineProperties(au.prototype,uu);var cu=function(t){function e(e){void 0===e&&(e={}),t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={$done:{configurable:!0}};return e.prototype.logger=function(){},e.prototype.$on=function(t,e,r){var n=this;void 0===r&&(r=null);this.validate(t,e);var o=this.takeFromStore(t);if(!1===o)return this.logger("($on)",t+" callback is not in lazy store"),this.addToNormalStore(t,"on",e,r);this.logger("($on)",t+" found in lazy store");var i=0;return o.forEach((function(o){var a=o[0],u=o[1],c=o[2];if(c&&"on"!==c)throw new Error("You are trying to register an event already been taken by other type: "+c);n.run(e,a,r||u),i+=n.addToNormalStore(t,"on",e,r||u)})),i},e.prototype.$once=function(t,e,r){void 0===r&&(r=null),this.validate(t,e);var n=this.takeFromStore(t);this.normalStore;if(!1===n)return this.logger("($once)",t+" not in the lazy store"),this.addToNormalStore(t,"once",e,r);this.logger("($once)",n);var o=Array.from(n)[0],i=o[0],a=o[1],u=o[2];if(u&&"once"!==u)throw new Error("You are trying to register an event already been taken by other type: "+u);this.run(e,i,r||a),this.$off(t)},e.prototype.$only=function(t,e,r){var n=this;void 0===r&&(r=null),this.validate(t,e);var o=!1,i=this.takeFromStore(t);(this.normalStore.has(t)||(this.logger("($only)",t+" add to store"),o=this.addToNormalStore(t,"only",e,r)),!1!==i)&&(this.logger("($only)",t+" found data in lazy store to execute"),Array.from(i).forEach((function(t){var o=t[0],i=t[1],a=t[2];if(a&&"only"!==a)throw new Error("You are trying to register an event already been taken by other type: "+a);n.run(e,o,r||i)})));return o},e.prototype.$onlyOnce=function(t,e,r){void 0===r&&(r=null),this.validate(t,e);var n=!1,o=this.takeFromStore(t);if(this.normalStore.has(t)||(this.logger("($onlyOnce)",t+" add to store"),n=this.addToNormalStore(t,"onlyOnce",e,r)),!1!==o){this.logger("($onlyOnce)",o);var i=Array.from(o)[0],a=i[0],u=i[1],c=i[2];if(c&&"onlyOnce"!==c)throw new Error("You are trying to register an event already been taken by other type: "+c);this.run(e,a,r||u),this.$off(t)}return n},e.prototype.$replace=function(t,e,r,n){if(void 0===r&&(r=null),void 0===n&&(n="on"),this.validateType(n)){this.$off(t);var o=this["$"+n];return Reflect.apply(o,this,[t,e,r])}throw new Error(n+" is not supported!")},e.prototype.$trigger=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1),this.validateEvt(t);var o=0,i=this.normalStore;if(this.logger("($trigger)","normalStore",i),i.has(t)){var a=this.$queue(t,e,r,n);if(this.logger("($trigger)",t,"found; add to queue: ",a),!0===a)return!1;for(var u=Array.from(i.get(t)),c=u.length,s=!1,f=0;f0;)n[o]=arguments[o+2];if(t.has(e)?(this.logger("(addToStore)",e+" existed"),r=t.get(e)):(this.logger("(addToStore)","create new Set for "+e),r=new Set),n.length>2)if(Array.isArray(n[0])){var i=n[2];this.checkTypeInLazyStore(e,i)||r.add(n)}else this.checkContentExist(n,r)||(this.logger("(addToStore)","insert new",n),r.add(n));else r.add(n);return t.set(e,r),[t,r.size]},e.prototype.checkContentExist=function(t,e){return!!Array.from(e).filter((function(e){return e[0]===t[0]})).length},e.prototype.checkTypeInStore=function(t,e){this.validateEvt(t,e);var r=this.$get(t,!0);return!1===r||!r.filter((function(t){var r=t[3];return e!==r})).length},e.prototype.checkTypeInLazyStore=function(t,e){this.validateEvt(t,e);var r=this.lazyStore.get(t);return this.logger("(checkTypeInLazyStore)",r),!!r&&!!Array.from(r).filter((function(t){return t[2]!==e})).length},e.prototype.addToNormalStore=function(t,e,r,n){if(void 0===n&&(n=null),this.logger("(addToNormalStore)",t,e,"try to add to normal store"),this.checkTypeInStore(t,e)){this.logger("(addToNormalStore)",e+" can add to "+t+" normal store");var o=this.hashFnToKey(r),i=[this.normalStore,t,o,r,n,e],a=Reflect.apply(this.addToStore,this,i),u=a[0],c=a[1];return this.normalStore=u,c}return!1},e.prototype.addToLazyStore=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1);var o=[this.lazyStore,t,this.toArray(e),r];n&&o.push(n);var i=Reflect.apply(this.addToStore,this,o),a=i[0],u=i[1];return this.lazyStore=a,u},e.prototype.toArray=function(t){return Array.isArray(t)?t:[t]},r.normalStore.set=function(t){ou.set(this,t)},r.normalStore.get=function(){return ou.get(this)},r.lazyStore.set=function(t){iu.set(this,t)},r.lazyStore.get=function(){return iu.get(this)},e.prototype.hashFnToKey=function(t){return t.toString().split("").reduce((function(t,e){return(t=(t<<5)-t+e.charCodeAt(0))&t}),0)+""},Object.defineProperties(e.prototype,r),e}(au));function su(t,e,r){var n=e.contract,o=function(t){return Ho(t,ru,eu)}(e),i=new Xa(o,r);return tu(i,o,n,t)}return function(t,e){var r,n=(r=e.debugOn,new cu({logger:r?function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];t.unshift("[NBS]"),console.log.apply(null,t)}:void 0}));return e.contract&&Ea(e.contract)?su(n,e,t):nu(n,e,t)}})); +//# sourceMappingURL=core.js.map diff --git a/packages/@jsonql/client/core.js.map b/packages/@jsonql/client/core.js.map new file mode 100644 index 0000000000000000000000000000000000000000..8e5052b5db519594427ed7d73ec3559acb09cd1e --- /dev/null +++ b/packages/@jsonql/client/core.js.map @@ -0,0 +1 @@ +{"version":3,"file":"core.js","sources":["node_modules/store/plugins/defaults.js","node_modules/store/plugins/expire.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i 0) { + url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&"); + } + + engine.open(options.method, url); + + // try catch for ie >=9 + try { + engine.withCredentials = !!options.withCredentials; + engine.timeout = options.timeout || 0; + if (responseType !== "stream") { + engine.responseType = responseType; + } + } catch (e) {} + + var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase]; + + // default content type + var _contentType = "application/x-www-form-urlencoded"; + // If the request data is json object, transforming it to json string, + // and set request content-type to "json". In browser, the data will + // be sent as RequestBody instead of FormData + if (utils.trim((customContentType || "").toLowerCase()) === _contentType) { + data = utils.formatParams(data); + } else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) { + _contentType = 'application/json;charset=utf-8'; + data = JSON.stringify(data); + } + //If user doesn't set content-type, set default. + if (!(customContentType || needQuery)) { + options.headers[contentType] = _contentType; + } + + for (var k in options.headers) { + if (k === contentType && utils.isFormData(data)) { + // Delete the content-type, Let the browser set it + delete options.headers[k]; + } else { + try { + // In browser environment, some header fields are readonly, + // write will cause the exception . + engine.setRequestHeader(k, options.headers[k]); + } catch (e) {} + } + } + + function onresult(handler, data, type) { + enqueueIfLocked(responseInterceptor.p, function () { + if (handler) { + //如果失败,添加请求信息 + if (type) { + data.request = options; + } + var ret = handler.call(responseInterceptor, data, Promise); + data = ret === undefined ? data : ret; + } + if (!isPromise(data)) { + data = Promise[type === 0 ? "resolve" : "reject"](data); + } + data.then(function (d) { + resolve(d); + }).catch(function (e) { + reject(e); + }); + }); + } + + function onerror(e) { + e.engine = engine; + onresult(responseInterceptor.onerror, e, -1); + } + + function Err(msg, status) { + this.message = msg; + this.status = status; + } + + engine.onload = function () { + try { + // The xhr of IE9 has not response field + var response = engine.response || engine.responseText; + if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1 + // Some third engine implementation may transform the response text to json object automatically, + // so we should test the type of response before transforming it + && !utils.isObject(response)) { + response = JSON.parse(response); + } + + var headers = engine.responseHeaders; + // In browser + if (!headers) { + headers = {}; + var items = (engine.getAllResponseHeaders() || "").split("\r\n"); + items.pop(); + items.forEach(function (e) { + if (!e) { return; } + var key = e.split(":")[0]; + headers[key] = engine.getResponseHeader(key); + }); + } + var status = engine.status; + var statusText = engine.statusText; + var _data = { data: response, headers: headers, status: status, statusText: statusText }; + // The _response filed of engine is set in adapter which be called in engine-wrapper.js + utils.merge(_data, engine._response); + if (status >= 200 && status < 300 || status === 304) { + _data.engine = engine; + _data.request = options; + onresult(responseInterceptor.handler, _data, 0); + } else { + var e = new Err(statusText, status); + e.response = _data; + onerror(e); + } + } catch (e) { + onerror(new Err(e.msg, engine.status)); + } + }; + + engine.onerror = function (e) { + onerror(new Err(e.msg || "Network Error", 0)); + }; + + engine.ontimeout = function () { + onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1)); + }; + engine._options = options; + setTimeout(function () { + engine.send(needQuery ? null : data); + }, 0); + } + + enqueueIfLocked(requestInterceptor.p, function () { + utils.merge(options, JSON.parse(JSON.stringify(_this.config))); + var headers = options.headers; + headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || ""; + delete headers[contentTypeLowerCase]; + options.body = data || options.body; + url = utils.trim(url || ""); + options.method = options.method.toUpperCase(); + options.url = url; + var ret = options; + if (requestInterceptorHandler) { + ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options; + } + if (!isPromise(ret)) { + ret = Promise.resolve(ret); + } + ret.then(function (d) { + //if options continue + if (d === options) { + makeRequest(d); + } else { + resolve(d); + } + }, function (err) { + reject(err); + }); + }); + }); + promise.engine = engine; + return promise; + } + }, { + key: "all", + value: function all(promises) { + return Promise.all(promises); + } + }, { + key: "spread", + value: function spread(callback) { + return function (arr) { + return callback.apply(null, arr); + }; + } + }]); + + return Fly; + }(); + + //For typeScript + + + Fly.default = Fly; + + ["get", "post", "put", "patch", "head", "delete"].forEach(function (e) { + Fly.prototype[e] = function (url, data, option) { + return this.request(url, data, utils.merge({ method: e }, option)); + }; + }); + ["lock", "unlock", "clear"].forEach(function (e) { + Fly.prototype[e] = function () { + this.interceptors.request[e](); + }; + }); + module.exports = Fly; + + /***/ }) + /******/ ]); + }); + }); + + var Fly$1 = unwrapExports(fly); + + // the core stuff to id if it's calling with jsonql + var DATA_KEY = 'data'; + var ERROR_KEY = 'error'; + + var JSONQL_PATH = 'jsonql'; + // according to the json query spec + var CONTENT_TYPE = 'application/vnd.api+json'; + var CHARSET = 'charset=utf-8'; + var DEFAULT_HEADER = { + 'Accept': CONTENT_TYPE, + 'Content-Type': [ CONTENT_TYPE, CHARSET ].join(';') + }; + + // export const INDEX = 'index'; use INDEX_KEY instead + var DEFAULT_TYPE = 'any'; + // new jsonp + var JSONP_CALLBACK_NAME = 'jsonqlJsonpCallback'; + + // methods allow + var API_REQUEST_METHODS = ['POST', 'PUT']; + // for contract-cli + var KEY_WORD = 'continue'; + + var TYPE_KEY = 'type'; + var OPTIONAL_KEY = 'optional'; + var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word + var ARGS_KEY = 'args'; + var CHECKER_KEY = 'checker'; + var ALIAS_KEY = 'alias'; + var LOGIN_NAME = 'login'; + var ISSUER_NAME = LOGIN_NAME; // legacy issue need to replace them later + var LOGOUT_NAME = 'logout'; + + var AUTH_HEADER = 'Authorization'; + var BEARER = 'Bearer'; + + // for client use @TODO need to clean this up some of them are not in use + var CREDENTIAL_STORAGE_KEY = 'credential'; + var CLIENT_STORAGE_KEY = 'storageKey'; + var CLIENT_AUTH_KEY = 'authKey'; + // contract key + var CONTRACT_KEY_NAME = 'X-JSONQL-CV-KEY'; + var SHOW_CONTRACT_DESC_PARAM = {desc: 'y'}; + + var OR_SEPERATOR = '|'; + + var STRING_TYPE = 'string'; + var BOOLEAN_TYPE = 'boolean'; + var ARRAY_TYPE = 'array'; + var OBJECT_TYPE = 'object'; + + var NUMBER_TYPE = 'number'; + var ARRAY_TYPE_LFT = 'array.<'; + var ARRAY_TYPE_RGT = '>'; + + var NO_ERROR_MSG = 'No message'; + var NO_STATUS_CODE = -1; + var RESULT_PROP_NAME = 'onResult'; + var ERROR_PROP_NAME = 'onError'; + var HSA_ALGO = 'HS256'; + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Built-in value references. */ + var Symbol$1 = root.Symbol; + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Built-in value references. */ + var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsZWJ = '\\u200d'; + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f', + reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', + rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', + rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, + rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange$1 + ']', + rsCombo = '[' + rsComboRange$1 + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange$1 + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange$1 + ']?', + rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** `Object#toString` result references. */ + var boolTag = '[object Boolean]'; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** `Object#toString` result references. */ + var numberTag = '[object Number]'; + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN$1(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** `Object#toString` result references. */ + var stringTag = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** Built-in value references. */ + var getPrototype = overArg(Object.getPrototypeOf, Object); + + /** `Object#toString` result references. */ + var objectTag = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto$2 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]'; + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$3.hasOwnProperty; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + } + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + arrayTag = '[object Array]', + boolTag$1 = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag$1 = '[object Number]', + objectTag$1 = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag$1 = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag$1] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag$1] = + typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag$1] = + typedArrayTags[weakMapTag] = false; + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** Detect free variable `exports`. */ + var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports$1 && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$4.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$3.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; + + return value === proto; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); + + /** Used for built-in method references. */ + var objectProto$6 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$6.hasOwnProperty; + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$4.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag$1 = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString$1.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto$2 = Function.prototype, + objectProto$7 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$2 = funcProto$2.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$5 = objectProto$7.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /* Built-in method references that are verified to be native. */ + var Map$1 = getNative(root, 'Map'); + + /* Built-in method references that are verified to be native. */ + var nativeCreate = getNative(Object, 'create'); + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$8 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$6 = objectProto$8.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$6.call(data, key) ? data[key] : undefined; + } + + /** Used for built-in method references. */ + var objectProto$9 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$7 = objectProto$9.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key); + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; + } + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map$1 || ListCache), + 'string': new Hash + }; + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED$2); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** Built-in value references. */ + var Uint8Array$1 = root.Uint8Array; + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$1 = 1, + COMPARE_UNORDERED_FLAG$1 = 2; + + /** `Object#toString` result references. */ + var boolTag$2 = '[object Boolean]', + dateTag$1 = '[object Date]', + errorTag$1 = '[object Error]', + mapTag$1 = '[object Map]', + numberTag$2 = '[object Number]', + regexpTag$1 = '[object RegExp]', + setTag$1 = '[object Set]', + stringTag$2 = '[object String]', + symbolTag$1 = '[object Symbol]'; + + var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$1 = '[object DataView]'; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$1 = Symbol$1 ? Symbol$1.prototype : undefined, + symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag$1: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag$1: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { + return false; + } + return true; + + case boolTag$2: + case dateTag$1: + case numberTag$2: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag$1: + return object.name == other.name && object.message == other.message; + + case regexpTag$1: + case stringTag$2: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag$1: + var convert = mapToArray; + + case setTag$1: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG$1; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag$1: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** Used for built-in method references. */ + var objectProto$a = Object.prototype; + + /** Built-in value references. */ + var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable$1.call(object, symbol); + }); + }; + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$2 = 1; + + /** Used for built-in method references. */ + var objectProto$b = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$8 = objectProto$b.hasOwnProperty; + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'); + + /* Built-in method references that are verified to be native. */ + var Promise$1 = getNative(root, 'Promise'); + + /* Built-in method references that are verified to be native. */ + var Set$1 = getNative(root, 'Set'); + + /* Built-in method references that are verified to be native. */ + var WeakMap$1 = getNative(root, 'WeakMap'); + + /** `Object#toString` result references. */ + var mapTag$2 = '[object Map]', + objectTag$2 = '[object Object]', + promiseTag = '[object Promise]', + setTag$2 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; + + var dataViewTag$2 = '[object DataView]'; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map$1), + promiseCtorString = toSource(Promise$1), + setCtorString = toSource(Set$1), + weakMapCtorString = toSource(WeakMap$1); + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$2) || + (Map$1 && getTag(new Map$1) != mapTag$2) || + (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || + (Set$1 && getTag(new Set$1) != setTag$2) || + (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag$1)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag$2 ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag$2; + case mapCtorString: return mapTag$2; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag$2; + case weakMapCtorString: return weakMapTag$1; + } + } + return result; + }; + } + + var getTag$1 = getTag; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$3 = 1; + + /** `Object#toString` result references. */ + var argsTag$2 = '[object Arguments]', + arrayTag$1 = '[object Array]', + objectTag$3 = '[object Object]'; + + /** Used for built-in method references. */ + var objectProto$c = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$9 = objectProto$c.hasOwnProperty; + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag$1 : getTag$1(object), + othTag = othIsArr ? arrayTag$1 : getTag$1(other); + + objTag = objTag == argsTag$2 ? objectTag$3 : objTag; + othTag = othTag == argsTag$2 ? objectTag$3 : othTag; + + var objIsObj = objTag == objectTag$3, + othIsObj = othTag == objectTag$3, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { + var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$4 = 1, + COMPARE_UNORDERED_FLAG$2 = 2; + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** Used to match property names within property paths. */ + var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** Used as references for various `Number` constants. */ + var INFINITY$1 = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$5 = 1, + COMPARE_UNORDERED_FLAG$3 = 2; + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); + }; + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ + function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** Detect free variable `exports`. */ + var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; + + /** Built-in value references. */ + var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, + allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** Built-in value references. */ + var objectCreate = Object.create; + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** Used for built-in method references. */ + var objectProto$d = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$a = objectProto$d.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty$a.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$e = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$b = objectProto$e.hasOwnProperty; + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$b.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max; + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeNow = Date.now; + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** Error message constants. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols$1 = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(baseIteratee(predicate))); + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate), baseForOwn); + } + + /** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ + + function notEmpty (a) { + if (isArray(a)) { + return true; + } + return a !== undefined && a !== null && trim(a) !== ''; + } + + // validator numbers + /** + * @2015-05-04 found a problem if the value is a number like string + * it will pass, so add a check if it's string before we pass to next + * @param {number} value expected value + * @return {boolean} true if OK + */ + var checkIsNumber = function(value) { + return isString(value) ? false : !isNaN$1( parseFloat(value) ) + }; + + // validate string type + /** + * @param {string} value expected value + * @return {boolean} true if OK + */ + var checkIsString = function(value) { + return (trim(value) !== '') ? isString(value) : false; + }; + + // check for boolean + /** + * @param {boolean} value expected + * @return {boolean} true if OK + */ + var checkIsBoolean = function(value) { + return isBoolean(value); + }; + + // validate any thing only check if there is something + /** + * @param {*} value the value + * @param {boolean} [checkNull=true] strict check if there is null value + * @return {boolean} true is OK + */ + var checkIsAny = function(value, checkNull) { + if ( checkNull === void 0 ) checkNull = true; + + if (!isUndefined(value) && value !== '' && trim(value) !== '') { + if (checkNull === false || (checkNull === true && !isNull(value))) { + return true; + } + } + return false; + }; + + // Good practice rule - No magic number + + var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; + var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; + var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; + // @TODO the jsdoc return array. and we should also allow array syntax + var DEFAULT_TYPE$1 = DEFAULT_TYPE; + var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; + var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; + + var TYPE_KEY$1 = TYPE_KEY; + var OPTIONAL_KEY$1 = OPTIONAL_KEY; + var ENUM_KEY$1 = ENUM_KEY; + var ARGS_KEY$1 = ARGS_KEY; + var CHECKER_KEY$1 = CHECKER_KEY; + var ALIAS_KEY$1 = ALIAS_KEY; + + var ARRAY_TYPE$1 = ARRAY_TYPE; + var OBJECT_TYPE$1 = OBJECT_TYPE; + var STRING_TYPE$1 = STRING_TYPE; + var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; + var NUMBER_TYPE$1 = NUMBER_TYPE; + var KEY_WORD$1 = KEY_WORD; + var OR_SEPERATOR$1 = OR_SEPERATOR; + + // not actually in use + // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; + + // primitive types + + /** + * this is a wrapper method to call different one based on their type + * @param {string} type to check + * @return {function} a function to handle the type + */ + var combineFn = function(type) { + switch (type) { + case NUMBER_TYPE$1: + return checkIsNumber; + case STRING_TYPE$1: + return checkIsString; + case BOOLEAN_TYPE$1: + return checkIsBoolean; + default: + return checkIsAny; + } + }; + + // validate array type + + /** + * @param {array} value expected + * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well + * @return {boolean} true if OK + */ + var checkIsArray = function(value, type) { + if ( type === void 0 ) type=''; + + if (isArray(value)) { + if (type === '' || trim(type)==='') { + return true; + } + // we test it in reverse + // @TODO if the type is an array (OR) then what? + // we need to take into account this could be an array + var c = value.filter(function (v) { return !combineFn(type)(v); }); + return !(c.length > 0) + } + return false; + }; + + /** + * check if it matches the array. pattern + * @param {string} type + * @return {boolean|array} false means NO, always return array + */ + var isArrayLike$1 = function(type) { + // @TODO could that have something like array<> instead of array.<>? missing the dot? + // because type script is Array without the dot + if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { + var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); + if (_type.indexOf(OR_SEPERATOR$1)) { + return _type.split(OR_SEPERATOR$1) + } + return [_type] + } + return false; + }; + + /** + * we might encounter something like array. then we need to take it apart + * @param {object} p the prepared object for processing + * @param {string|array} type the type came from + * @return {boolean} for the filter to operate on + */ + var arrayTypeHandler = function(p, type) { + var arg = p.arg; + // need a special case to handle the OR type + // we need to test the args instead of the type(s) + if (type.length > 1) { + return !arg.filter(function (v) { return ( + !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) + ); }).length; + } + // type is array so this will be or! + return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; + }; + + // validate object type + /** + * @TODO if provide with the keys then we need to check if the key:value type as well + * @param {object} value expected + * @param {array} [keys=null] if it has the keys array to compare as well + * @return {boolean} true if OK + */ + var checkIsObject = function(value, keys) { + if ( keys === void 0 ) keys=null; + + if (isPlainObject(value)) { + if (!keys) { + return true; + } + if (checkIsArray(keys)) { + // please note we DON'T care if some is optional + // plese refer to the contract.json for the keys + return !keys.filter(function (key) { + var _value = value[key.name]; + return !(key.type.length > key.type.filter(function (type) { + var tmp; + if (!isUndefined(_value)) { + if ((tmp = isArrayLike$1(type)) !== false) { + return !arrayTypeHandler({arg: _value}, tmp) + // return tmp.filter(t => !checkIsArray(_value, t)).length; + // @TODO there might be an object within an object with keys as well :S + } + return !combineFn(type)(_value) + } + return true; + }).length) + }).length; + } + } + return false; + }; + + /** + * fold this into it's own function to handler different object type + * @param {object} p the prepared object for process + * @return {boolean} + */ + var objectTypeHandler = function(p) { + var arg = p.arg; + var param = p.param; + var _args = [arg]; + if (Array.isArray(param.keys) && param.keys.length) { + _args.push(param.keys); + } + // just simple check + return checkIsObject.apply(null, _args) + }; + + /** + * This is a custom error to throw when server throw a 406 + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var Jsonql406Error = /*@__PURE__*/(function (Error) { + function Jsonql406Error() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + // We can't access the static name from an instance + // but we can do it like this + this.className = Jsonql406Error.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Jsonql406Error); + } + } + + if ( Error ) Jsonql406Error.__proto__ = Error; + Jsonql406Error.prototype = Object.create( Error && Error.prototype ); + Jsonql406Error.prototype.constructor = Jsonql406Error; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 406; + }; + + staticAccessors.name.get = function () { + return 'Jsonql406Error'; + }; + + Object.defineProperties( Jsonql406Error, staticAccessors ); + + return Jsonql406Error; + }(Error)); + + /** + * This is a custom error to throw when server throw a 500 + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var Jsonql500Error = /*@__PURE__*/(function (Error) { + function Jsonql500Error() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = Jsonql500Error.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Jsonql500Error); + } + } + + if ( Error ) Jsonql500Error.__proto__ = Error; + Jsonql500Error.prototype = Object.create( Error && Error.prototype ); + Jsonql500Error.prototype.constructor = Jsonql500Error; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 500; + }; + + staticAccessors.name.get = function () { + return 'Jsonql500Error'; + }; + + Object.defineProperties( Jsonql500Error, staticAccessors ); + + return Jsonql500Error; + }(Error)); + + /** + * This is a custom error to throw when pass credential but fail + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlAuthorisationError = /*@__PURE__*/(function (Error) { + function JsonqlAuthorisationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlAuthorisationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlAuthorisationError); + } + } + + if ( Error ) JsonqlAuthorisationError.__proto__ = Error; + JsonqlAuthorisationError.prototype = Object.create( Error && Error.prototype ); + JsonqlAuthorisationError.prototype.constructor = JsonqlAuthorisationError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 401; + }; + + staticAccessors.name.get = function () { + return 'JsonqlAuthorisationError'; + }; + + Object.defineProperties( JsonqlAuthorisationError, staticAccessors ); + + return JsonqlAuthorisationError; + }(Error)); + + /** + * This is a custom error when not supply the credential and try to get contract + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlContractAuthError = /*@__PURE__*/(function (Error) { + function JsonqlContractAuthError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlContractAuthError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlContractAuthError); + } + } + + if ( Error ) JsonqlContractAuthError.__proto__ = Error; + JsonqlContractAuthError.prototype = Object.create( Error && Error.prototype ); + JsonqlContractAuthError.prototype.constructor = JsonqlContractAuthError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 401; + }; + + staticAccessors.name.get = function () { + return 'JsonqlContractAuthError'; + }; + + Object.defineProperties( JsonqlContractAuthError, staticAccessors ); + + return JsonqlContractAuthError; + }(Error)); + + /** + * This is a custom error to throw when the resolver throw error and capture inside the middleware + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlResolverAppError = /*@__PURE__*/(function (Error) { + function JsonqlResolverAppError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlResolverAppError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlResolverAppError); + } + } + + if ( Error ) JsonqlResolverAppError.__proto__ = Error; + JsonqlResolverAppError.prototype = Object.create( Error && Error.prototype ); + JsonqlResolverAppError.prototype.constructor = JsonqlResolverAppError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 500; + }; + + staticAccessors.name.get = function () { + return 'JsonqlResolverAppError'; + }; + + Object.defineProperties( JsonqlResolverAppError, staticAccessors ); + + return JsonqlResolverAppError; + }(Error)); + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode = function () { + try { + if (!isBrowser() && global$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI() { + if (isBrowser()) { + return 'browser' + } + if (isNode()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + } + + if ( Error ) JsonqlBaseError.__proto__ = Error; + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI() + }; + + return JsonqlBaseError; + }(Error)); + + /** + * This is a custom error to throw when could not find the resolver + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlResolverNotFoundError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlResolverNotFoundError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlResolverNotFoundError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlResolverNotFoundError); + } + } + + if ( JsonqlBaseError ) JsonqlResolverNotFoundError.__proto__ = JsonqlBaseError; + JsonqlResolverNotFoundError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlResolverNotFoundError.prototype.constructor = JsonqlResolverNotFoundError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 404; + }; + + staticAccessors.name.get = function () { + return 'JsonqlResolverNotFoundError'; + }; + + Object.defineProperties( JsonqlResolverNotFoundError, staticAccessors ); + + return JsonqlResolverNotFoundError; + }(JsonqlBaseError)); + + // this get throw from within the checkOptions when run through the enum failed + var JsonqlEnumError = /*@__PURE__*/(function (Error) { + function JsonqlEnumError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlEnumError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlEnumError); + } + } + + if ( Error ) JsonqlEnumError.__proto__ = Error; + JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); + JsonqlEnumError.prototype.constructor = JsonqlEnumError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlEnumError'; + }; + + Object.defineProperties( JsonqlEnumError, staticAccessors ); + + return JsonqlEnumError; + }(Error)); + + // this will throw from inside the checkOptions + var JsonqlTypeError = /*@__PURE__*/(function (Error) { + function JsonqlTypeError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlTypeError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlTypeError); + } + } + + if ( Error ) JsonqlTypeError.__proto__ = Error; + JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); + JsonqlTypeError.prototype.constructor = JsonqlTypeError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlTypeError'; + }; + + Object.defineProperties( JsonqlTypeError, staticAccessors ); + + return JsonqlTypeError; + }(Error)); + + // allow supply a custom checker function + // if that failed then we throw this error + var JsonqlCheckerError = /*@__PURE__*/(function (Error) { + function JsonqlCheckerError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlCheckerError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlCheckerError); + } + } + + if ( Error ) JsonqlCheckerError.__proto__ = Error; + JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); + JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlCheckerError'; + }; + + Object.defineProperties( JsonqlCheckerError, staticAccessors ); + + return JsonqlCheckerError; + }(Error)); + + // custom validation error class + // when validaton failed + var JsonqlValidationError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) JsonqlValidationError.__proto__ = JsonqlBaseError; + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; + }(JsonqlBaseError)); + + /** + * This is a custom error to throw whenever a error happen inside the jsonql + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlError); + // this.detail = this.stack; + } + } + + if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; + JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlError.prototype.constructor = JsonqlError; + + var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlError'; + }; + + staticAccessors.statusCode.get = function () { + return NO_STATUS_CODE; + }; + + Object.defineProperties( JsonqlError, staticAccessors ); + + return JsonqlError; + }(JsonqlBaseError)); + + // this is from an example from Koa team to use for internal middleware ctx.throw + // but after the test the res.body part is unable to extract the required data + // I keep this one here for future reference + + var JsonqlServerError = /*@__PURE__*/(function (Error) { + function JsonqlServerError(statusCode, message) { + Error.call(this, message); + this.statusCode = statusCode; + this.className = JsonqlServerError.name; + } + + if ( Error ) JsonqlServerError.__proto__ = Error; + JsonqlServerError.prototype = Object.create( Error && Error.prototype ); + JsonqlServerError.prototype.constructor = JsonqlServerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlServerError'; + }; + + Object.defineProperties( JsonqlServerError, staticAccessors ); + + return JsonqlServerError; + }(Error)); + + // server side + + var errors = /*#__PURE__*/Object.freeze({ + Jsonql406Error: Jsonql406Error, + Jsonql500Error: Jsonql500Error, + JsonqlAuthorisationError: JsonqlAuthorisationError, + JsonqlContractAuthError: JsonqlContractAuthError, + JsonqlResolverAppError: JsonqlResolverAppError, + JsonqlResolverNotFoundError: JsonqlResolverNotFoundError, + JsonqlEnumError: JsonqlEnumError, + JsonqlTypeError: JsonqlTypeError, + JsonqlCheckerError: JsonqlCheckerError, + JsonqlValidationError: JsonqlValidationError, + JsonqlError: JsonqlError, + JsonqlServerError: JsonqlServerError + }); + + // this will add directly to the then call in each http call + var JsonqlError$1 = JsonqlError; + + /** + * We can not just check something like result.data what if the result if false? + * @param {object} obj the result object + * @param {string} key we want to check if its exist or not + * @return {boolean} true on found + */ + var isKeyInObject = function (obj, key) { + var keys = Object.keys(obj); + return !!keys.filter(function (k) { return key === k; }).length; + }; + + /** + * It will ONLY have our own jsonql specific implement check + * @param {object} result the server return result + * @return {object} this will just throw error + */ + function clientErrorsHandler(result) { + if (isKeyInObject(result, 'error')) { + var error = result.error; + var className = error.className; + var name = error.name; + var errorName = className || name; + // just throw the whole thing back + var msg = error.message || NO_ERROR_MSG; + var detail = error.detail || error; + if (errorName && errors[errorName]) { + throw new errors[className](msg, detail) + } + throw new JsonqlError$1(msg, detail) + } + // pass through to the next + return result; + } + + /** + * this will put into generator call at the very end and catch + * the error throw from inside then throw again + * this is necessary because we split calls inside and the throw + * will not reach the actual client unless we do it this way + * @param {object} e Error + * @return {void} just throw + */ + function finalCatch(e) { + // this is a hack to get around the validateAsync not actually throw error + // instead it just rejected it with the array of failed parameters + if (Array.isArray(e)) { + // if we want the message then I will have to create yet another function + // to wrap this function to provide the name prop + throw new JsonqlValidationError('', e) + } + var msg = e.message || NO_ERROR_MSG; + var detail = e.detail || e; + switch (true) { + case e instanceof Jsonql406Error: + throw new Jsonql406Error(msg, detail) + case e instanceof Jsonql500Error: + throw new Jsonql500Error(msg, detail) + case e instanceof JsonqlAuthorisationError: + throw new JsonqlAuthorisationError(msg, detail) + case e instanceof JsonqlContractAuthError: + throw new JsonqlContractAuthError(msg, detail) + case e instanceof JsonqlResolverAppError: + throw new JsonqlResolverAppError(msg, detail) + case e instanceof JsonqlResolverNotFoundError: + throw new JsonqlResolverNotFoundError(msg, detail) + case e instanceof JsonqlEnumError: + throw new JsonqlEnumError(msg, detail) + case e instanceof JsonqlTypeError: + throw new JsonqlTypeError(msg, detail) + case e instanceof JsonqlCheckerError: + throw new JsonqlCheckerError(msg, detail) + case e instanceof JsonqlValidationError: + throw new JsonqlValidationError(msg, detail) + case e instanceof JsonqlServerError: + throw new JsonqlServerError(msg, detail) + default: + throw new JsonqlError(msg, detail) + } + } + + /** + * just a simple util for helping to debug + * @param {array} args arguments + * @return {void} + */ + function log() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.console) { + Reflect.apply(console.log, console, args); + } + } catch(e) {} + } + + // move the index.js code here that make more sense to find where things are + // import debug from 'debug' + // const debugFn = debug('jsonql-params-validator:validator') + // also export this for use in other places + + /** + * We need to handle those optional parameter without a default value + * @param {object} params from contract.json + * @return {boolean} for filter operation false is actually OK + */ + var optionalHandler = function( params ) { + var arg = params.arg; + var param = params.param; + if (notEmpty(arg)) { + // debug('call optional handler', arg, params); + // loop through the type in param + return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } + ).length) + } + return false; + }; + + /** + * actually picking the validator + * @param {*} type for checking + * @param {*} value for checking + * @return {boolean} true on OK + */ + var validateHandler = function(type, value) { + var tmp; + switch (true) { + case type === OBJECT_TYPE$1: + // debugFn('call OBJECT_TYPE') + return !objectTypeHandler(value) + case type === ARRAY_TYPE$1: + // debugFn('call ARRAY_TYPE') + return !checkIsArray(value.arg) + // @TODO when the type is not present, it always fall through here + // so we need to find a way to actually pre-check the type first + // AKA check the contract.json map before running here + case (tmp = isArrayLike$1(type)) !== false: + // debugFn('call ARRAY_LIKE: %O', value) + return !arrayTypeHandler(value, tmp) + default: + return !combineFn(type)(value.arg) + } + }; + + /** + * it get too longer to fit in one line so break it out from the fn below + * @param {*} arg value + * @param {object} param config + * @return {*} value or apply default value + */ + var getOptionalValue = function(arg, param) { + if (!isUndefined(arg)) { + return arg; + } + return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) + }; + + /** + * padding the arguments with defaultValue if the arguments did not provide the value + * this will be the name export + * @param {array} args normalized arguments + * @param {array} params from contract.json + * @return {array} merge the two together + */ + var normalizeArgs = function(args, params) { + // first we should check if this call require a validation at all + // there will be situation where the function doesn't need args and params + if (!checkIsArray(params)) { + // debugFn('params value', params) + throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) + } + if (params.length === 0) { + return []; + } + if (!checkIsArray(args)) { + throw new JsonqlError(ARGS_NOT_ARRAY_ERR) + } + // debugFn(args, params); + // fall through switch + switch(true) { + case args.length == params.length: // standard + log(1); + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, + param: params[i] + } + ); }) + case params[0].variable === true: // using spread syntax + log(2); + var type = params[0].type; + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, // keep the index for reference + param: params[i] || { type: type, name: '_' } + } + ); }) + // with optional defaultValue parameters + case args.length < params.length: + log(3); + return params.map(function (param, i) { return ( + { + param: param, + index: i, + arg: getOptionalValue(args[i], param), + optional: param.optional || false + } + ); }) + // this one pass more than it should have anything after the args.length will be cast as any type + case args.length > params.length: + log(4); + var ctn = params.length; + // this happens when we have those array. type + var _type = [ DEFAULT_TYPE$1 ]; + // we only looking at the first one, this might be a @BUG + /* + if ((tmp = isArrayLike(params[0].type[0])) !== false) { + _type = tmp; + } */ + // if we use the params as guide then the rest will get throw out + // which is not what we want, instead, anything without the param + // will get a any type and optional flag + return args.map(function (arg, i) { + var optional = i >= ctn ? true : !!params[i].optional; + var param = params[i] || { type: _type, name: ("_" + i) }; + return { + arg: optional ? getOptionalValue(arg, param) : arg, + index: i, + param: param, + optional: optional + } + }) + // @TODO find out if there is more cases not cover + default: // this should never happen + log(5); + // debugFn('args', args) + // debugFn('params', params) + // this is unknown therefore we just throw it! + throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) + } + }; + + // what we want is after the validaton we also get the normalized result + // which is with the optional property if the argument didn't provide it + /** + * process the array of params back to their arguments + * @param {array} result the params result + * @return {array} arguments + */ + var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; + + /** + * validator main interface + * @param {array} args the arguments pass to the method call + * @param {array} params from the contract for that method + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {array} empty array on success, or failed parameter and reasons + */ + var validateSync = function(args, params, withResult) { + var obj; + + if ( withResult === void 0 ) withResult = false; + var cleanArgs = normalizeArgs(args, params); + var checkResult = cleanArgs.filter(function (p) { + // v1.4.4 this fixed the problem, the root level optional is from the last fn + if (p.optional === true || p.param.optional === true) { + return optionalHandler(p) + } + // because array of types means OR so if one pass means pass + return !(p.param.type.length > p.param.type.filter( + function (type) { return validateHandler(type, p); } + ).length) + }); + // using the same convention we been using all this time + return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) + }; + + /** + * A wrapper method that return promise + * @param {array} args arguments + * @param {array} params from contract.json + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {object} promise.then or catch + */ + var validateAsync = function(args, params, withResult) { + if ( withResult === void 0 ) withResult = false; + + return new Promise(function (resolver, rejecter) { + var result = validateSync(args, params, withResult); + if (withResult) { + return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY]) + : resolver(result[DATA_KEY]) + } + // the different is just in the then or catch phrase + return result.length ? rejecter(result) : resolver([]) + }) + }; + + /** + * @param {array} arr Array for check + * @param {*} value target + * @return {boolean} true on successs + */ + var isInArray = function(arr, value) { + return !!arr.filter(function (a) { return a === value; }).length; + }; + + var isKeyInObject$1 = function(obj, key) { + var keys = Object.keys(obj); + return isInArray(keys, key) + }; + + // just not to make my head hurt + var isEmpty = function (value) { return !notEmpty(value); }; + + /** + * Map the alias to their key then grab their value over + * @param {object} config the user supplied config + * @param {object} appProps the default option map + * @return {object} the config keys replaced with the appProps key by the ALIAS + */ + function mapAliasConfigKeys(config, appProps) { + // need to do two steps + // 1. take key with alias key + var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); + if (isEqual(aliasMap, {})) { + return config; + } + return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) + } + + /** + * We only want to run the valdiation against the config (user supplied) value + * but keep the defaultOptions untouch + * @param {object} config configuraton supplied by user + * @param {object} appProps the default options map + * @return {object} the pristine values that will add back to the final output + */ + function preservePristineValues(config, appProps) { + // @BUG this will filter out those that is alias key + // we need to first map the alias keys back to their full key + var _config = mapAliasConfigKeys(config, appProps); + // take the default value out + var pristineValues = mapValues( + omitBy(appProps, function (value, key) { return isKeyInObject$1(_config, key); }), + function (value) { return value.args; } + ); + // for testing the value + var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !isKeyInObject$1(_config, key); }); + // output + return { + pristineValues: pristineValues, + checkAgainstAppProps: checkAgainstAppProps, + config: _config // passing this correct values back + } + } + + /** + * This will take the value that is ONLY need to check + * @param {object} config that one + * @param {object} props map for creating checking + * @return {object} put that arg into the args + */ + function processConfigAction(config, props) { + // debugFn('processConfigAction', props) + // v.1.2.0 add checking if its mark optional and the value is empty then pass + return mapValues(props, function (value, key) { + var obj, obj$1; + + return ( + isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) + ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) + : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) + ); + } + ) + } + + /** + * Quick transform + * @TODO we should only validate those that is pass from the config + * and pass through those values that is from the defaultOptions + * @param {object} opts that one + * @param {object} appProps mutation configuration options + * @return {object} put that arg into the args + */ + function prepareArgsForValidation(opts, appProps) { + var ref = preservePristineValues(opts, appProps); + var config = ref.config; + var pristineValues = ref.pristineValues; + var checkAgainstAppProps = ref.checkAgainstAppProps; + // output + return [ + processConfigAction(config, checkAgainstAppProps), + pristineValues + ] + } + + // breaking the whole thing up to see what cause the multiple calls issue + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:validation') + + /** + * just make sure it returns an array to use + * @param {*} arg input + * @return {array} output + */ + var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; + + /** + * DIY in array + * @param {array} arr to check against + * @param {*} value to check + * @return {boolean} true on OK + */ + var inArray = function (arr, value) { return ( + !!arr.filter(function (v) { return v === value; }).length + ); }; + + /** + * break out to make the code easier to read + * @param {object} value to process + * @param {function} cb the validateSync + * @return {array} empty on success + */ + function validateHandler$1(value, cb) { + var obj; + + // cb is the validateSync methods + var args = [ + [ value[ARGS_KEY$1] ], + [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] + ]; + // debugFn('validateHandler', args) + return Reflect.apply(cb, null, args) + } + + /** + * Check against the enum value if it's provided + * @param {*} value to check + * @param {*} enumv to check against if it's not false + * @return {boolean} true on OK + */ + var enumHandler = function (value, enumv) { + if (checkIsArray(enumv)) { + return inArray(enumv, value) + } + return true; + }; + + /** + * Allow passing a function to check the value + * There might be a problem here if the function is incorrect + * and that will makes it hard to debug what is going on inside + * @TODO there could be a few feature add to this one under different circumstance + * @param {*} value to check + * @param {function} checker for checking + */ + var checkerHandler = function (value, checker) { + try { + return isFunction(checker) ? checker.apply(null, [value]) : false; + } catch (e) { + return false; + } + }; + + /** + * Taken out from the runValidaton this only validate the required values + * @param {array} args from the config2argsAction + * @param {function} cb validateSync + * @return {array} of configuration values + */ + function runValidationAction(cb) { + return function (value, key) { + // debugFn('runValidationAction', key, value) + if (value[KEY_WORD$1]) { + return value[ARGS_KEY$1] + } + var check = validateHandler$1(value, cb); + if (check.length) { + log('runValidationAction', key, value); + throw new JsonqlTypeError(key, check) + } + if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { + log(ENUM_KEY$1, value[ENUM_KEY$1]); + throw new JsonqlEnumError(key) + } + if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { + log(CHECKER_KEY$1, value[CHECKER_KEY$1]); + throw new JsonqlCheckerError(key) + } + return value[ARGS_KEY$1] + } + } + + /** + * @param {object} args from the config2argsAction + * @param {function} cb validateSync + * @return {object} of configuration values + */ + function runValidation(args, cb) { + var argsForValidate = args[0]; + var pristineValues = args[1]; + // turn the thing into an array and see what happen here + // debugFn('_args', argsForValidate) + var result = mapValues(argsForValidate, runValidationAction(cb)); + return merge(result, pristineValues) + } + + // this is port back from the client to share across all projects + + /** + * @param {object} config user provide configuration option + * @param {object} appProps mutation configuration options + * @param {object} constProps the immutable configuration options + * @param {function} cb the validateSync method + * @return {object} Promise resolve merge config object + */ + function checkOptionsSync(config, appProps, constProps, cb) { + if ( config === void 0 ) config = {}; + + return merge( + runValidation( + prepareArgsForValidation(config, appProps), + cb + ), + constProps + ) + } + + // create function to construct the config entry so we don't need to keep building object + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:construct-config'); + /** + * @param {*} args value + * @param {string} type for value + * @param {boolean} [optional=false] + * @param {boolean|array} [enumv=false] + * @param {boolean|function} [checker=false] + * @return {object} config entry + */ + function constructConfigFn(args, type, optional, enumv, checker, alias) { + if ( optional === void 0 ) optional=false; + if ( enumv === void 0 ) enumv=false; + if ( checker === void 0 ) checker=false; + if ( alias === void 0 ) alias=false; + + var base = {}; + base[ARGS_KEY] = args; + base[TYPE_KEY] = type; + if (optional === true) { + base[OPTIONAL_KEY] = true; + } + if (checkIsArray(enumv)) { + base[ENUM_KEY] = enumv; + } + if (isFunction(checker)) { + base[CHECKER_KEY] = checker; + } + if (isString(alias)) { + base[ALIAS_KEY] = alias; + } + return base; + } + + // export also create wrapper methods + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:index'); + + /** + * This has a different interface + * @param {*} value to supply + * @param {string|array} type for checking + * @param {object} params to map against the config check + * @param {array} params.enumv NOT enum + * @param {boolean} params.optional false then nothing + * @param {function} params.checker need more work on this one later + * @param {string} params.alias mostly for cmd + */ + var createConfig = function (value, type, params) { + if ( params === void 0 ) params = {}; + + // Note the enumv not ENUM + // const { enumv, optional, checker, alias } = params; + // let args = [value, type, optional, enumv, checker, alias]; + var o = params[OPTIONAL_KEY]; + var e = params[ENUM_KEY]; + var c = params[CHECKER_KEY]; + var a = params[ALIAS_KEY]; + return constructConfigFn.apply(null, [value, type, o, e, c, a]) + }; + + // copy of above but it's sync + var checkConfig = function(validateSync) { + return function(config, appProps, constantProps) { + if ( constantProps === void 0 ) constantProps = {}; + + return checkOptionsSync(config, appProps, constantProps, validateSync) + } + }; + + // export + var isString$1 = checkIsString; + var isArray$1 = checkIsArray; + var validateAsync$1 = validateAsync; + + var createConfig$1 = createConfig; + var checkConfig$1 = checkConfig(validateSync); + + // breaking out the inner methods generator in here + + /** + * generate authorisation specific methods + * @param {object} jsonqlInstance instance of this + * @param {string} name of method + * @param {object} opts configuration + * @param {object} contract to match + * @return {function} for use + */ + var authMethodGenerator = function (jsonqlInstance, name, opts, contract) { + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var params = contract.auth[name].params; + var values = params.map(function (p, i) { return args[i]; }); + var header = args[params.length] || {}; + return validateAsync$1(args, params) + .then(function () { return jsonqlInstance + .query + .apply(jsonqlInstance, [name, values, header]); } + ) + .catch(finalCatch) + } + }; + + /** + * Here just generate the methods calls + * @param {object} jsonqlInstance what it said + * @param {object} ee event emitter + * @param {object} config configuration + * @param {object} contract the map + * @return {object} with mapped methods + */ + function methodsGenerator(jsonqlInstance, ee, config, contract) { + var obj = {query: {}, mutation: {}}; + // process the query first + var loop = function ( queryFn ) { + // to keep it clean we use a param to id the auth method + // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn; + // generate the query method + obj.query[queryFn] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var params = contract.query[queryFn].params; + var _args = params.map(function (param, i) { return args[i]; }); + // debug('query', queryFn, _params); + // @TODO this need to change + // the +1 parameter is the extra headers we want to pass + var header = args[params.length] || {}; + // @TODO validate against the type + return validateAsync$1(_args, params) + .then(function () { return jsonqlInstance + .query + .apply(jsonqlInstance, [queryFn, _args, header]); } + ) + .catch(finalCatch) + }; + }; + + for (var queryFn in contract.query) loop( queryFn ); + // process the mutation, the reason the mutation has a fixed number of parameters + // there is only the payload, and conditions parameters + // plus a header at the end + var loop$1 = function ( mutationFn ) { + obj.mutation[mutationFn] = function (payload, conditions, header) { + if ( header === void 0 ) header = {}; + + var args = [payload, conditions]; + var params = contract.mutation[mutationFn].params; + return validateAsync$1(args, params) + .then(function () { return jsonqlInstance + .mutation + .apply(jsonqlInstance, [mutationFn, payload, conditions, header]); } + ) + .catch(finalCatch) + }; + }; + + for (var mutationFn in contract.mutation) loop$1( mutationFn ); + // there is only one call issuer we want here + if (config.enableAuth && contract.auth) { + obj.auth = {}; // v1.3.1 add back the auth prop name + var loginHandlerName = config.loginHandlerName; + var logoutHandlerName = config.logoutHandlerName; + if (contract.auth[loginHandlerName]) { + // changing to the name the config specify + obj.auth[loginHandlerName] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract); + return fn.apply(null, args) + .then(jsonqlInstance.postLoginAction) + .then(function (token) { + ee.$trigger(ISSUER_NAME, token); + return token; + }) + }; + } + if (contract.auth[logoutHandlerName]) { + obj.auth[logoutHandlerName] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract); + return fn.apply(null, args) + .then(jsonqlInstance.postLogoutAction) + .then(function (r) { + ee.$trigger(LOGOUT_NAME, r); + return r; + }) + }; + } else { + obj.auth[logoutHandlerName] = function () { + jsonqlInstance.postLogoutAction(KEY_WORD); + ee.$trigger(LOGOUT_NAME, KEY_WORD); + }; + } + } + return obj; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray$2 = Array.isArray; + + var global$1$1 = (typeof global$1 !== "undefined" ? global$1 : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$1 = typeof global$1$1 == 'object' && global$1$1 && global$1$1.Object === Object && global$1$1; + + /** Detect free variable `self`. */ + var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')(); + + /** Built-in value references. */ + var Symbol$2 = root$1.Symbol; + + /** Used for built-in method references. */ + var objectProto$f = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$c = objectProto$f.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$2 = objectProto$f.toString; + + /** Built-in value references. */ + var symToStringTag$2 = Symbol$2 ? Symbol$2.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag$1(value) { + var isOwn = hasOwnProperty$c.call(value, symToStringTag$2), + tag = value[symToStringTag$2]; + + try { + value[symToStringTag$2] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString$2.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag$2] = tag; + } else { + delete value[symToStringTag$2]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1$1 = objectProto$1$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString$1(value) { + return nativeObjectToString$1$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag$1 = '[object Null]', + undefinedTag$1 = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1$1 = Symbol$2 ? Symbol$2.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag$1(value) { + if (value == null) { + return value === undefined ? undefinedTag$1 : nullTag$1; + } + return (symToStringTag$1$1 && symToStringTag$1$1 in Object(value)) + ? getRawTag$1(value) + : objectToString$1(value); + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg$1(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** Built-in value references. */ + var getPrototype$1 = overArg$1(Object.getPrototypeOf, Object); + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$1(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var objectTag$4 = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto$3 = Function.prototype, + objectProto$2$1 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$3 = funcProto$3.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1$1 = objectProto$2$1.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString$1 = funcToString$3.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject$1(value) { + if (!isObjectLike$1(value) || baseGetTag$1(value) != objectTag$4) { + return false; + } + var proto = getPrototype$1(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString$3.call(Ctor) == objectCtorString$1; + } + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$2 = Symbol$2 ? Symbol$2.prototype : undefined, + symbolToString$1 = symbolProto$2 ? symbolProto$2.toString : undefined; + + /** `Object#toString` result references. */ + var stringTag$3 = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString$2(value) { + return typeof value == 'string' || + (!isArray$2(value) && isObjectLike$1(value) && baseGetTag$1(value) == stringTag$3); + } + + // bunch of generic helpers + + /** + * DIY in Array + * @param {array} arr to check from + * @param {*} value to check against + * @return {boolean} true on found + */ + var inArray$1 = function (arr, value) { return !!arr.filter(function (a) { return a === value; }).length; }; + + /** + * @param {object} obj for search + * @param {string} key target + * @return {boolean} true on success + */ + var isKeyInObject$2 = function(obj, key) { + var keys = Object.keys(obj); + return inArray$1(keys, key) + }; + + /** + * create a event name + * @param {string[]} args + * @return {string} event name for use + */ + var createEvt = function () { + var arguments$1 = arguments; + + var args = [], len = arguments.length; + while ( len-- ) { args[ len ] = arguments$1[ len ]; } + + return args.join('_'); + }; + + /** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ + var timestamp = function (sec) { + if ( sec === void 0 ) { sec = false; } + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; + }; + + /** + * @return {object} _cb as key with timestamp + */ + var cacheBurst = function () { return ({ _cb: timestamp() }); }; + + // the core stuff to id if it's calling with jsonql + var DATA_KEY$1 = 'data'; + var ERROR_KEY$1 = 'error'; + + // @TODO remove this is not in use + // export const CLIENT_CONFIG_FILE = '.clients.json'; + // export const CONTRACT_CONFIG_FILE = 'jsonql-contract-config.js'; + // type of resolvers + var QUERY_NAME = 'query'; + var MUTATION_NAME = 'mutation'; + var SOCKET_NAME = 'socket'; + // for calling the mutation + var PAYLOAD_PARAM_NAME = 'payload'; + var CONDITION_PARAM_NAME = 'condition'; + var QUERY_ARG_NAME = 'args'; + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser$1 = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode$1 = function () { + try { + if (!isBrowser$1() && global$1$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI$1() { + if (isBrowser$1()) { + return 'browser' + } + if (isNode$1()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError$1 = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var arguments$1 = arguments; + + var args = [], len = arguments.length; + while ( len-- ) { args[ len ] = arguments$1[ len ]; } + + Error.apply(this, args); + } + + if ( Error ) { JsonqlBaseError.__proto__ = Error; } + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI$1() + }; + + return JsonqlBaseError; + }(Error)); + + // custom validation error class + // when validaton failed + var JsonqlValidationError$1 = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var arguments$1 = arguments; + + var args = [], len = arguments.length; + while ( len-- ) { args[ len ] = arguments$1[ len ]; } + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) { JsonqlValidationError.__proto__ = JsonqlBaseError; } + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; + }(JsonqlBaseError$1)); + + // split the contract into the node side and the generic side + /** + * Check if the json is a contract file or not + * @param {object} contract json object + * @return {boolean} true + */ + function checkIsContract(contract) { + return isPlainObject$1(contract) + && ( + isKeyInObject$2(contract, QUERY_NAME) + || isKeyInObject$2(contract, MUTATION_NAME) + || isKeyInObject$2(contract, SOCKET_NAME) + ) + } + + /** + * @param {*} args arguments to send + *@return {object} formatted payload + */ + var formatPayload = function (args) { + var obj; + + return ( + ( obj = {}, obj[QUERY_ARG_NAME] = args, obj ) + ); + }; + + /** + * Get name from the payload (ported back from jsonql-koa) + * @param {*} payload to extract from + * @return {string} name + */ + function getNameFromPayload(payload) { + return Object.keys(payload)[0] + } + + /** + * @param {string} resolverName name of function + * @param {array} [args=[]] from the ...args + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ + function createQuery(resolverName, args, jsonp) { + var obj; + + if ( args === void 0 ) { args = []; } + if ( jsonp === void 0 ) { jsonp = false; } + if (isString$2(resolverName) && isArray$2(args)) { + var payload = formatPayload(args); + if (jsonp === true) { + return payload; + } + return ( obj = {}, obj[resolverName] = payload, obj ) + } + throw new JsonqlValidationError$1("[createQuery] expect resolverName to be string and args to be array!", { resolverName: resolverName, args: args }) + } + + /** + * @param {string} resolverName name of function + * @param {*} payload to send + * @param {object} [condition={}] for what + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ + function createMutation(resolverName, payload, condition, jsonp) { + var obj; + + if ( condition === void 0 ) { condition = {}; } + if ( jsonp === void 0 ) { jsonp = false; } + var _payload = {}; + _payload[PAYLOAD_PARAM_NAME] = payload; + _payload[CONDITION_PARAM_NAME] = condition; + if (jsonp === true) { + return _payload; + } + if (isString$2(resolverName)) { + return ( obj = {}, obj[resolverName] = _payload, obj ) + } + throw new JsonqlValidationError$1("[createMutation] expect resolverName to be string!", { resolverName: resolverName, payload: payload, condition: condition }) + } + + // ported from http-client + + /** + * handle the return data + * @param {object} result return from server + * @return {object} strip the data part out, or if the error is presented + */ + var resultHandler = function (result) { return ( + (isKeyInObject$2(result, DATA_KEY$1) && !isKeyInObject$2(result, ERROR_KEY$1)) ? result[DATA_KEY$1] : result + ); }; + + // exportfor ES modules + + // alias + var isContract = checkIsContract; + + // take only the module part which is what we use here + /** + * @param {object} jsonqlInstance the init instance of jsonql client + * @param {object} contract the static contract + * @return {object} contract may be from server + */ + var getContractFromConfig = function(jsonqlInstance, contract) { + if ( contract === void 0 ) contract = {}; + + if (isContract(contract)) { + return Promise.resolve(contract) + } + return jsonqlInstance.getContract() + }; + + // export some constants as well + // since it's only use here there is no point of adding it to the constants module + // or may be we add it back later + var ENDPOINT_TABLE = 'endpoint'; + var USERDATA_TABLE = 'userdata'; + + // This generator will use the old style + + + /** + * Group all the same methods together + * @param {object} ee event emitter + * @param {string} type query, mutation or auth + * @param {string} resolverName use as the guide + * @param {array} args from the call + * @return {function} the handler itself + */ + var handler = function (ee, type) { + // we don't run validate here because we want until the contract is ready + return function (resolverName) { + var args = [], len = arguments.length - 1; + while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ]; + + return ( + new Promise(function (resolver, rejecter) { + // this are the callbacks + ee.$only(createEvt(type, resolverName, RESULT_PROP_NAME), resolver); + ee.$only(createEvt(type, resolverName, ERROR_PROP_NAME), rejecter); + // this is the main call + ee.$trigger(type, { resolverName: resolverName, args: args }); + }) + ); + } + }; + + /** + * @param {object} ee eventEmitter + * @param {object} contract the map + * @param {object} config configuration + */ + var validateRegisteredEvents = function (ee, contract, config) { + var storedEvt = ee.$queues; + var debug = config.debugOn; + if (debug) { + console.info('(validateRegisteredEvents)', 'storedEvt', storedEvt); + } + storedEvt.forEach(function (args) { + var type = args[0]; + var payload = args[1]; + var resolverName = payload.resolverName; + if (debug) { + console.info('(validateRegisteredEvents)', type, resolverName); + } + if (!contract[type][resolverName]) { + throw new Error((type + "." + resolverName + " not existed in contract!")) + } + }); + }; + + /** + * set up all the event handlers once the contract is ready + * @param {object} jsonqlInstance what the name said + * @param {object} ee event emitter + * @param {object} config the configuration + * @param {object} contract the map + * @return {void} nothing + */ + function setupEventHandlers(jsonqlInstance, ee, config, contract) { + var methods = methodsGenerator(jsonqlInstance, ee, config, contract); + validateRegisteredEvents(ee, contract, config); + // create handler + var loop = function ( type ) { + // setup event listeners - only one listener per type + ee.$only(type, function(ref) { + var resolverName = ref.resolverName; + var args = ref.args; + + if (methods[type][resolverName]) { + Reflect.apply(methods[type][resolverName], null, args) + .then(function (result) { + ee.$trigger(createEvt(type, resolverName, RESULT_PROP_NAME), result); + }) + .catch(function (err) { + ee.$trigger(createEvt(type, resolverName, ERROR_PROP_NAME), err); + }); + } else { + console.error((resolverName + " is not defined in the contract!")); + } + }); + }; + + for (var type in methods) loop( type ); + // all done now release the queue if any + setTimeout(function () { + ee.$suspend = false; + }, 1); + } + + /** + * @param {object} jsonqlInstance jsonql class instance + * @param {object} config options + * @param {object} contractPromise an unresolve promise + * @param {object} ee eventEmitter + * @return {object} constructed functions call + */ + var generator = function (jsonqlInstance, config, contractPromise, ee) { + ee.$suspend = true; // hold all the calls + // wait for the promise to resolve + contractPromise.then(function (contract) { + setupEventHandlers(jsonqlInstance, ee, config, contract); + }); + // construct the api + var obj = { + query: handler(ee, 'query'), + mutation: handler(ee, 'mutation'), + auth: handler(ee, 'auth') + }; + // allow getting the token for valdiate agains the socket + obj.getToken = function () { return jsonqlInstance.rawAuthToken; }; + // this will pass to the ws-client if needed + // obj.eventEmitter = ee; + // this will require a param + if (config.exposeContract) { + obj.getContract = function () { return jsonqlInstance.get(); }; + } + if (config.enableAuth) { + obj.userdata = function () { return jsonqlInstance.userdata; }; + } + obj.version = '0.1.0'; + // output + return obj; + }; + + var assign = make_assign(); + var create = make_create(); + var trim$1 = make_trim(); + var Global = (typeof window !== 'undefined' ? window : commonjsGlobal); + + var util = { + assign: assign, + create: create, + trim: trim$1, + bind: bind, + slice: slice, + each: each, + map: map, + pluck: pluck, + isList: isList, + isFunction: isFunction$1, + isObject: isObject$1, + Global: Global + }; + + function make_assign() { + if (Object.assign) { + return Object.assign + } else { + return function shimAssign(obj, props1, props2, etc) { + var arguments$1 = arguments; + + for (var i = 1; i < arguments.length; i++) { + each(Object(arguments$1[i]), function(val, key) { + obj[key] = val; + }); + } + return obj + } + } + } + + function make_create() { + if (Object.create) { + return function create(obj, assignProps1, assignProps2, etc) { + var assignArgsList = slice(arguments, 1); + return assign.apply(this, [Object.create(obj)].concat(assignArgsList)) + } + } else { + function F() {} // eslint-disable-line no-inner-declarations + return function create(obj, assignProps1, assignProps2, etc) { + var assignArgsList = slice(arguments, 1); + F.prototype = obj; + return assign.apply(this, [new F()].concat(assignArgsList)) + } + } + } + + function make_trim() { + if (String.prototype.trim) { + return function trim(str) { + return String.prototype.trim.call(str) + } + } else { + return function trim(str) { + return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '') + } + } + } + + function bind(obj, fn) { + return function() { + return fn.apply(obj, Array.prototype.slice.call(arguments, 0)) + } + } + + function slice(arr, index) { + return Array.prototype.slice.call(arr, index || 0) + } + + function each(obj, fn) { + pluck(obj, function(val, key) { + fn(val, key); + return false + }); + } + + function map(obj, fn) { + var res = (isList(obj) ? [] : {}); + pluck(obj, function(v, k) { + res[k] = fn(v, k); + return false + }); + return res + } + + function pluck(obj, fn) { + if (isList(obj)) { + for (var i=0; i= 0; i--) { + var key = localStorage$1().key(i); + fn(read(key), key); + } + } + + function remove(key) { + return localStorage$1().removeItem(key) + } + + function clearAll() { + return localStorage$1().clear() + } + + // cookieStorage is useful Safari private browser mode, where localStorage + // doesn't work but cookies do. This implementation is adopted from + // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage + + + var Global$2 = util.Global; + var trim$2 = util.trim; + + var cookieStorage = { + name: 'cookieStorage', + read: read$1, + write: write$1, + each: each$3, + remove: remove$1, + clearAll: clearAll$1, + }; + + var doc = Global$2.document; + + function read$1(key) { + if (!key || !_has(key)) { return null } + var regexpStr = "(?:^|.*;\\s*)" + + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"; + return unescape(doc.cookie.replace(new RegExp(regexpStr), "$1")) + } + + function each$3(callback) { + var cookies = doc.cookie.split(/; ?/g); + for (var i = cookies.length - 1; i >= 0; i--) { + if (!trim$2(cookies[i])) { + continue + } + var kvp = cookies[i].split('='); + var key = unescape(kvp[0]); + var val = unescape(kvp[1]); + callback(val, key); + } + } + + function write$1(key, data) { + if(!key) { return } + doc.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; + } + + function remove$1(key) { + if (!key || !_has(key)) { + return + } + doc.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + } + + function clearAll$1() { + each$3(function(_, key) { + remove$1(key); + }); + } + + function _has(key) { + return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc.cookie) + } + + var defaults = defaultsPlugin; + + function defaultsPlugin() { + var defaultValues = {}; + + return { + defaults: defaults, + get: get + } + + function defaults(_, values) { + defaultValues = values; + } + + function get(super_fn, key) { + var val = super_fn(); + return (val !== undefined ? val : defaultValues[key]) + } + } + + var namespace = 'expire_mixin'; + + var expire = expirePlugin; + + function expirePlugin() { + var expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace); + + return { + set: expire_set, + get: expire_get, + remove: expire_remove, + getExpiration: getExpiration, + removeExpiredKeys: removeExpiredKeys + } + + function expire_set(super_fn, key, val, expiration) { + if (!this.hasNamespace(namespace)) { + expirations.set(key, expiration); + } + return super_fn() + } + + function expire_get(super_fn, key) { + if (!this.hasNamespace(namespace)) { + _checkExpiration.call(this, key); + } + return super_fn() + } + + function expire_remove(super_fn, key) { + if (!this.hasNamespace(namespace)) { + expirations.remove(key); + } + return super_fn() + } + + function getExpiration(_, key) { + return expirations.get(key) + } + + function removeExpiredKeys(_) { + var keys = []; + this.each(function(val, key) { + keys.push(key); + }); + for (var i=0; i + // This work is free. You can redistribute it and/or modify it + // under the terms of the WTFPL, Version 2 + // For more information see LICENSE.txt or http://www.wtfpl.net/ + // + // For more information, the home page: + // http://pieroxy.net/blog/pages/lz-string/testing.html + // + // LZ-based compression algorithm, version 1.4.4 + var LZString = (function() { + + // private property + var f = String.fromCharCode; + var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"; + var baseReverseDic = {}; + + function getBaseValue(alphabet, character) { + if (!baseReverseDic[alphabet]) { + baseReverseDic[alphabet] = {}; + for (var i=0 ; i>> 8; + buf[i*2+1] = current_value % 256; + } + return buf; + }, + + //decompress from uint8array (UCS-2 big endian format) + decompressFromUint8Array:function (compressed) { + if (compressed===null || compressed===undefined){ + return LZString.decompress(compressed); + } else { + var buf=new Array(compressed.length/2); // 2 bytes per character + for (var i=0, TotalLen=buf.length; i> 1; + } + } else { + value = 1; + for (i=0 ; i> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i=0 ; i> 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + // Add wc to the dictionary. + context_dictionary[context_wc] = context_dictSize++; + context_w = String(context_c); + } + } + + // Output the code for w. + if (context_w !== "") { + if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) { + if (context_w.charCodeAt(0)<256) { + for (i=0 ; i> 1; + } + } else { + value = 1; + for (i=0 ; i> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i=0 ; i> 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + } + + // Mark the end of the stream + value = 2; + for (i=0 ; i> 1; + } + + // Flush the last char + while (true) { + context_data_val = (context_data_val << 1); + if (context_data_position == bitsPerChar-1) { + context_data.push(getCharFromInt(context_data_val)); + break; + } + else { context_data_position++; } + } + return context_data.join(''); + }, + + decompress: function (compressed) { + if (compressed == null) { return ""; } + if (compressed == "") { return null; } + return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); }); + }, + + _decompress: function (length, resetValue, getNextValue) { + var dictionary = [], + next, + enlargeIn = 4, + dictSize = 4, + numBits = 3, + entry = "", + result = [], + i, + w, + bits, resb, maxpower, power, + c, + data = {val:getNextValue(0), position:resetValue, index:1}; + + for (i = 0; i < 3; i += 1) { + dictionary[i] = i; + } + + bits = 0; + maxpower = Math.pow(2,2); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + switch (next = bits) { + case 0: + bits = 0; + maxpower = Math.pow(2,8); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + c = f(bits); + break; + case 1: + bits = 0; + maxpower = Math.pow(2,16); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + c = f(bits); + break; + case 2: + return ""; + } + dictionary[3] = c; + w = c; + result.push(c); + while (true) { + if (data.index > length) { + return ""; + } + + bits = 0; + maxpower = Math.pow(2,numBits); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + switch (c = bits) { + case 0: + bits = 0; + maxpower = Math.pow(2,8); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + dictionary[dictSize++] = f(bits); + c = dictSize-1; + enlargeIn--; + break; + case 1: + bits = 0; + maxpower = Math.pow(2,16); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + dictionary[dictSize++] = f(bits); + c = dictSize-1; + enlargeIn--; + break; + case 2: + return result.join(''); + } + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + if (dictionary[c]) { + entry = dictionary[c]; + } else { + if (c === dictSize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + result.push(entry); + + // Add w+entry[0] to the dictionary. + dictionary[dictSize++] = w + entry.charAt(0); + enlargeIn--; + + w = entry; + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + } + } + }; + return LZString; + })(); + + if( module != null ) { + module.exports = LZString; + } + }); + + var compression = compressionPlugin; + + function compressionPlugin() { + return { + get: get, + set: set, + } + + function get(super_fn, key) { + var val = super_fn(key); + if (!val) { return val } + var decompressed = lzString.decompress(val); + // fallback to existing values that are not compressed + return (decompressed == null) ? val : this._deserialize(decompressed) + } + + function set(super_fn, key, val) { + var compressed = lzString.compress(this._serialize(val)); + super_fn(key, compressed); + } + } + + // sort of persist on the user side + + var storages = [localStorage_1, cookieStorage]; + var plugins = [defaults, expire, events, compression]; + + var localStore = storeEngine.createStore(storages, plugins); + + var Global$3 = util.Global; + + var sessionStorage_1 = { + name: 'sessionStorage', + read: read$2, + write: write$2, + each: each$5, + remove: remove$2, + clearAll: clearAll$2 + }; + + function sessionStorage() { + return Global$3.sessionStorage + } + + function read$2(key) { + return sessionStorage().getItem(key) + } + + function write$2(key, data) { + return sessionStorage().setItem(key, data) + } + + function each$5(fn) { + for (var i = sessionStorage().length - 1; i >= 0; i--) { + var key = sessionStorage().key(i); + fn(read$2(key), key); + } + } + + function remove$2(key) { + return sessionStorage().removeItem(key) + } + + function clearAll$2() { + return sessionStorage().clear() + } + + // session store with watch + + var storages$1 = [sessionStorage_1, cookieStorage]; + var plugins$1 = [defaults, expire]; + + var sessionStore = storeEngine.createStore(storages$1, plugins$1); + + // export store interface + + // export back the raw version for development purposes + var localStore$1 = localStore; + var sessionStore$1 = sessionStore; + + /** + * The code was extracted from: + * https://github.com/davidchambers/Base64.js + */ + + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + + InvalidCharacterError.prototype = new Error(); + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + function polyfill (input) { + var str = String(input).replace(/=+$/, ''); + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + } + + + var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; + + function b64DecodeUnicode(str) { + return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { + var code = p.charCodeAt(0).toString(16).toUpperCase(); + if (code.length < 2) { + code = '0' + code; + } + return '%' + code; + })); + } + + var base64_url_decode = function(str) { + var output = str.replace(/-/g, "+").replace(/_/g, "/"); + switch (output.length % 4) { + case 0: + break; + case 2: + output += "=="; + break; + case 3: + output += "="; + break; + default: + throw "Illegal base64url string!"; + } + + try{ + return b64DecodeUnicode(output); + } catch (err) { + return atob(output); + } + }; + + function InvalidTokenError(message) { + this.message = message; + } + + InvalidTokenError.prototype = new Error(); + InvalidTokenError.prototype.name = 'InvalidTokenError'; + + var lib = function (token,options) { + if (typeof token !== 'string') { + throw new InvalidTokenError('Invalid token specified'); + } + + options = options || {}; + var pos = options.header === true ? 0 : 1; + try { + return JSON.parse(base64_url_decode(token.split('.')[pos])); + } catch (e) { + throw new InvalidTokenError('Invalid token specified: ' + e.message); + } + }; + + var InvalidTokenError_1 = InvalidTokenError; + lib.InvalidTokenError = InvalidTokenError_1; + + // bunch of generic helpers + + /** + * @param {string} name the name part after the : + * @param {string} baseName the base before the : + */ + var getDebug = function (name, baseName) { + if ( baseName === void 0 ) baseName = 'jsonql'; + + return debug$1(baseName).extend(name) + }; + + /** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ + var timestamp$1 = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; + }; + + // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js + var performance = global$1.performance || {}; + var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + + // koa specific methods + var debug = getDebug("koa", "jsonql-utils"); + + // when the user is login with the jwt + /** + * We only check the nbf and exp + * @param {object} token for checking + * @return {object} token on success + */ + function validate(token) { + var start = token.iat || timestamp$1(); + // we only check the exp for the time being + if (token.exp) { + if (start >= token.exp) { + var expired = new Date(token.exp).toISOString(); + throw new JsonqlError(("Token has expired on " + expired), token) + } + } + return token; + } + + /** + * The browser client version it has far fewer options and it doesn't verify it + * because it couldn't this is the job for the server + * @TODO we need to add some extra proessing here to check for the exp field + * @param {string} token to decrypted + * @return {object} decrypted object + */ + function jwtDecode(token) { + if (isString$1(token)) { + var t = lib(token); + return validate(t) + } + throw new JsonqlError('Token must be a string!') + } + + var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; + + var appProps = { + algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), + expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), + notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), + audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), + subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), + issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), + noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), + header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), + keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), + mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) + }; + + // base HttpClass + + // extract the one we need + var POST = API_REQUEST_METHODS[0]; + var PUT = API_REQUEST_METHODS[1]; + + var _log = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.console) { + Reflect.apply(console.log, null, args); + } + } catch(e) {} + }; + + var HttpClass = function HttpClass(opts) { + // change the way how we init Fly + // flyio now become external depedencies and it makes it easier to switch + // @BUG should we run test to check if we have the windows object? + _log(opts); + this.fly = opts.Fly ? new opts.Fly() : new Fly(); + // to a different environment like WeChat mini app + this.opts = opts; + this.extraHeader = {}; + // @1.2.1 for adding query to the call on the fly + this.extraParams = {}; + // this.log('start up opts', opts); + this.reqInterceptor(); + this.resInterceptor(); + }; + + var prototypeAccessors = { headers: { configurable: true } }; + + // set headers for that one call + prototypeAccessors.headers.set = function (header) { + this.extraHeader = header; + }; + + /** + * Create the reusage request method + * @param {object} payload jsonql payload + * @param {object} options extra options add the request + * @param {object} headers extra headers add to the call + * @return {object} the fly request instance + */ + HttpClass.prototype.request = function request (payload, options, headers) { + var obj; + + if ( options === void 0 ) options = {}; + if ( headers === void 0 ) headers = {}; + this.headers = headers; + var params = merge({}, cacheBurst(), this.extraParams); + // @TODO need to add a jsonp url and payload + if (this.opts.enableJsonp) { + var resolverName = getNameFromPayload(payload); + params = merge({}, params, ( obj = {}, obj[JSONP_CALLBACK_NAME] = resolverName, obj )); + payload = payload[resolverName]; + } + return this.fly.request( + this.jsonqlEndpoint, + payload, + merge({}, { method: POST, params: params }, options) + ) + }; + + /** + * This will replace the create baseRequest method + * + */ + HttpClass.prototype.reqInterceptor = function reqInterceptor () { + var this$1 = this; + + this.fly.interceptors.request.use( + function (req) { + var headers = this$1.getHeaders(); + this$1.log('request interceptor call', headers); + + for (var key in headers) { + req.headers[key] = headers[key]; + } + return req; + } + ); + }; + + // @TODO + HttpClass.prototype.processJsonp = function processJsonp (result) { + return resultHandler(result) + }; + + /** + * This will be replacement of the first then call + * + */ + HttpClass.prototype.resInterceptor = function resInterceptor () { + var this$1 = this; + + var self = this; + var jsonp = self.opts.enableJsonp; + this.fly.interceptors.response.use( + function (res) { + this$1.log('response interceptor call'); + self.cleanUp(); + // now more processing here + // there is a problem if we throw the result.error here + // the original data is lost, so we need to do what we did before + // deal with that error in the first then instead + var result = isString$1(res.data) ? JSON.parse(res.data) : res.data; + if (jsonp) { + return self.processJsonp(result) + } + return resultHandler(result) + }, + // this get call when it's not 200 + function (err) { + self.cleanUp(); + console.error(err); + throw new JsonqlServerError('Server side error', err) + } + ); + }; + + /** + * Get the headers inject into the call + * @return {object} headers + */ + HttpClass.prototype.getHeaders = function getHeaders () { + if (this.opts.enableAuth) { + return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader) + } + return merge({}, DEFAULT_HEADER, this.extraHeader) + }; + + /** + * Post http call operation to clean up things we need + */ + HttpClass.prototype.cleanUp = function cleanUp () { + this.extraHeader = {}; + this.extraParams = {}; + }; + + /** + * GET for contract only + */ + HttpClass.prototype.get = function get () { + var this$1 = this; + + if (this.opts.showContractDesc) { + this.extraParams = merge({}, this.extraParams, SHOW_CONTRACT_DESC_PARAM); + } + return this.request({}, {method: 'GET'}, this.contractHeader) + .then(clientErrorsHandler) + .then(function (result) { + this$1.log('get contract result', result); + // when refresh the window the result is different! + // @TODO need to check the Koa side about why is that + // also it should set a flag if we want the description or not + if (result.cache && result.contract) { + return result.contract; + } + // just the normal result + return result + }) + }; + + /** + * POST to server - query + * @param {object} name of the resolver + * @param {array} args arguments + * @return {object} promise resolve to the resolver return + */ + HttpClass.prototype.query = function query (name, args) { + if ( args === void 0 ) args = []; + + return this.request(createQuery(name, args)) + .then(clientErrorsHandler) + }; + + /** + * PUT to server - mutation + * @param {string} name of resolver + * @param {object} payload what it said + * @param {object} conditions what it said + * @return {object} promise resolve to the resolver return + */ + HttpClass.prototype.mutation = function mutation (name, payload, conditions) { + if ( payload === void 0 ) payload = {}; + if ( conditions === void 0 ) conditions = {}; + + return this.request(createMutation(name, payload, conditions), {method: PUT}) + .then(clientErrorsHandler) + }; + + Object.defineProperties( HttpClass.prototype, prototypeAccessors ); + + // all the contract related methods will be here + + // export + var ContractClass = /*@__PURE__*/(function (HttpClass) { + function ContractClass(opts) { + HttpClass.call(this, opts); + } + + if ( HttpClass ) ContractClass.__proto__ = HttpClass; + ContractClass.prototype = Object.create( HttpClass && HttpClass.prototype ); + ContractClass.prototype.constructor = ContractClass; + + var prototypeAccessors = { contractHeader: { configurable: true } }; + + /** + * return the contract public api + * @return {object} contract + */ + ContractClass.prototype.getContract = function getContract () { + var contracts = this.readContract(); + this.log('getContract first call', contracts); + if (contracts && Array.isArray(contracts)) { + var contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]; + if (contract) { + return Promise.resolve(contract) + } + } + return this.get() + .then( this.storeContract.bind(this) ) + }; + + /** + * We are changing the way how to auth to get the contract.json + * Instead of in the url, we will be putting that key value in the header + * @return {object} header + */ + prototypeAccessors.contractHeader.get = function () { + var base = {}; + if (this.opts.contractKey !== false) { + base[this.opts.contractKeyName] = this.opts.contractKey; + } + return base; + }; + + /** + * Save the contract to local store + * @param {object} contract to save + * @return {object|boolean} false when its not a contract or contract on OK + */ + ContractClass.prototype.storeContract = function storeContract (contract) { + // first need to check if the contract is a contract + if (!isContract(contract)) { + throw new JsonqlValidationError("Contract is malformed!") + //return false; + } + var args = [contract]; + if (this.opts.contractExpired) { + var expired = parseFloat(this.opts.contractExpired); + if (!isNaN(expired) && expired > 0) { + args.push(expired); + } + } + // calling the setter + this.jsonqlContract = args; + // return it + this.log('storeContract return result', contract); + return contract; + }; + + /** + * return the contract from options or localStore + * @return {object} contract + */ + ContractClass.prototype.readContract = function readContract () { + var contract = isContract(this.opts.contract); + return contract ? this.opts.contract : localStore$1.get(this.opts.storageKey) + }; + + Object.defineProperties( ContractClass.prototype, prototypeAccessors ); + + return ContractClass; + }(HttpClass)); + + // this is the new auth class that integrate with the jsonql-jwt + // export + var AuthClass = /*@__PURE__*/(function (ContractClass) { + function AuthClass(opts) { + ContractClass.call(this, opts); + if (opts.enableAuth && opts.useJwt) { + this.setDecoder = jwtDecode; + } + } + + if ( ContractClass ) AuthClass.__proto__ = ContractClass; + AuthClass.prototype = Object.create( ContractClass && ContractClass.prototype ); + AuthClass.prototype.constructor = AuthClass; + + var prototypeAccessors = { userdata: { configurable: true },rawAuthToken: { configurable: true },setDecoder: { configurable: true } }; + + /** + * Getter to get the login userdata + * @return {mixed} userdata + */ + prototypeAccessors.userdata.get = function () { + return this.jsonqlUserdata; // see base-cls + }; + + /** + * Return the token from session store + * @return {string} token + */ + prototypeAccessors.rawAuthToken.get = function () { + // this should return from the base + return this.jsonqlToken; // see base-cls + }; + + /** + * Setter to add a decoder when retrieve user token + * @param {function} d a decoder + */ + prototypeAccessors.setDecoder.set = function (d) { + if (typeof d === 'function') { + this.decoder = d; + } + }; + + /** + * Setter after login success + * @TODO this move to a new class to handle multiple login + * @param {string} token to store + * @return {*} success store + */ + AuthClass.prototype.storeToken = function storeToken (token) { + return this.jsonqlToken = token; + }; + + /** + * for overwrite + * @param {string} token stored token + * @return {string} token + */ + AuthClass.prototype.decoder = function decoder (token) { + return token; + }; + + /** + * Construct the auth header + * @return {object} header + */ + AuthClass.prototype.getAuthHeader = function getAuthHeader () { + var obj; + + var token = this.rawAuthToken; + return token ? ( obj = {}, obj[this.opts.AUTH_HEADER] = (BEARER + " " + token), obj ) : {}; + }; + + Object.defineProperties( AuthClass.prototype, prototypeAccessors ); + + return AuthClass; + }(ContractClass)); + + // this the core of the internal storage management + + // This class will only focus on the storage system + var JsonqlBaseClient = /*@__PURE__*/(function (AuthCls) { + function JsonqlBaseClient(opts, Fly) { + if ( Fly === void 0 ) Fly = null; + + if (Fly) { + opts.Fly = Fly; + } + AuthCls.call(this, opts); + } + + if ( AuthCls ) JsonqlBaseClient.__proto__ = AuthCls; + JsonqlBaseClient.prototype = Object.create( AuthCls && AuthCls.prototype ); + JsonqlBaseClient.prototype.constructor = JsonqlBaseClient; + + var prototypeAccessors = { storeIt: { configurable: true },jsonqlEndpoint: { configurable: true },jsonqlContract: { configurable: true },jsonqlToken: { configurable: true },jsonqlUserdata: { configurable: true } }; + + // @TODO + prototypeAccessors.storeIt.set = function (args) { + console.info('storeIt', args); + // the args MUST contain [0] the key , [1] the content [2] optional expired in + if (isArray$1(args) && args.length >= 2) { + Reflect.apply(localStore$1.set, localStore$1, args); + } + throw new JsonqlValidationError("Expect argument to be array and least 2 items!") + }; + + // this table index key will drive the contract + // also it should not allow to change dynamicly + // because this is how different client can id itself + // OK this could be self manage because when init a new client + // it will add a new endpoint and we will know if they are the same or not + // but the check here + prototypeAccessors.jsonqlEndpoint.set = function (endpoint) { + var urls = localStore$1.get(ENDPOINT_TABLE) || []; + // should check if this url already existed? + if (!inArray$1(urls, endpoint)) { + urls.push(endpoint); + this.storeId = [ENDPOINT_TABLE, urls]; + this[ENDPOINT_TABLE + 'Index'] = urls.length - 1; + } + }; + + // by the time it call the save contract already been checked + prototypeAccessors.jsonqlContract.set = function (args) { + var key = this.opts.storageKey; + var _args = [ key ]; + var contract = args[0]; + var expired = args[1]; + // get the endpoint index + var contracts = localStore$1.get(key) || []; + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + _args.push(contracts); + if (expired) { + _args.push(expired); + } + if (this.opts.keepContract) { + this.storeIt = _args; + } + }; + + /** + * save token + * @param {string} token to store + * @return {string|boolean} false on failed + */ + prototypeAccessors.jsonqlToken.set = function (token) { + var key = CREDENTIAL_STORAGE_KEY; + var tokens = localStorage.get(key) || []; + if (!inArray$1(tokens, token)) { + var index = tokens.length - 1; + tokens[ index ] = token; + this[key + 'Index'] = index; + var args = [key, tokens]; + if (this.opts.tokenExpired) { + var expired = parseFloat(this.opts.tokenExpired); + if (!isNaN(expired) && expired > 0) { + var ts = timestamp(); + args.push( ts + parseFloat(expired) ); + } + } + this.storeIt = args; + // now decode it and store in the userdata + this.jsonqlUserdata = this.decoder(token); + return token; + } + return false; + }; + + /** + * this one will use the sessionStore + * basically we hook this onto the token store and decode it to store here + */ + prototypeAccessors.jsonqlUserdata.set = function (userdata) { + var args = [USERDATA_TABLE, userdata]; + if (userdata.exp) { + args.push(userdata.exp); + } + return Reflect.apply(localStore$1.set, localStore$1, args) + }; + + /** + * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point + * @return {string} the end point to call + */ + prototypeAccessors.jsonqlEndpoint.get = function () { + var urls = localStore$1.get(ENDPOINT_TABLE); + if (!urls) { + var ref = this.opts; + var hostname = ref.hostname; + var jsonqlPath = ref.jsonqlPath; + var url = [hostname, jsonqlPath].join('/'); + this.jsonqlEndpoint = url; + return url; + } + return urls[this[ENDPOINT_TABLE + 'Index']] + }; + + /** + * If already stored then return it by the end point index + * or false when there is none + * 1.2.0 start using the keepContract option (replace the useLocalStorage) + * @return {object|boolean} as described above + */ + prototypeAccessors.jsonqlContract.get = function () { + var key = this.opts.storageKey; + var contracts = localStore$1.get(key) || []; + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false + }; + + /** + * Jsonql token getter + * @return {string|boolean} false when failed + */ + prototypeAccessors.jsonqlToken.get = function () { + var key = CREDENTIAL_STORAGE_KEY; + var tokens = localStorage.get(key); + if (tokens) { + return tokens[ this[key + 'Index'] ] + } + return false; + }; + + /** + * this one store in the session store + * get login userdata decoded jwt + * @return {object|null} + */ + prototypeAccessors.jsonqlUserdata.get = function () { + return sessionStore$1.get(USERDATA_TABLE) + }; + + /** + * simple log + */ + JsonqlBaseClient.prototype.log = function log () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + if (this.opts.debugOn === true) { + Reflect.apply(console.info, console, args); + } + }; + + Object.defineProperties( JsonqlBaseClient.prototype, prototypeAccessors ); + + return JsonqlBaseClient; + }(AuthClass)); + + // export interface + + // all the client configuration options here + var constProps = { + contract: false, + MUTATION_ARGS: ['name', 'payload', 'conditions'], // this seems wrong? + CONTENT_TYPE: CONTENT_TYPE, + BEARER: BEARER, + AUTH_HEADER: AUTH_HEADER + }; + + // grab the localhost name and put into the hostname as default + var getHostName = function () { return ( + [window.location.protocol, window.location.host].join('//') + ); }; + + var appProps$1 = { + + hostname: createConfig$1(getHostName(), [STRING_TYPE]), // required the hostname + jsonqlPath: createConfig$1(JSONQL_PATH, [STRING_TYPE]), // The path on the server + + loginHandlerName: createConfig$1(ISSUER_NAME, [STRING_TYPE]), + logoutHandlerName: createConfig$1(LOGOUT_NAME, [STRING_TYPE]), + // add to koa v1.3.0 - this might remove in the future + enableJsonp: createConfig$1(false, [BOOLEAN_TYPE]), + enableAuth: createConfig$1(false, [BOOLEAN_TYPE]), + // enable useJwt by default + useJwt: createConfig$1(true, [BOOLEAN_TYPE]), + + // the header + // v1.2.0 we are using this option during the dev + // so it won't save anything to the localstorage and fetch a new contract + // whenever the browser reload + useLocalstorage: createConfig$1(true, [BOOLEAN_TYPE]), // should we store the contract into localStorage + storageKey: createConfig$1(CLIENT_STORAGE_KEY, [STRING_TYPE]),// the key to use when store into localStorage + authKey: createConfig$1(CLIENT_AUTH_KEY, [STRING_TYPE]),// the key to use when store into the sessionStorage + contractExpired: createConfig$1(0, [NUMBER_TYPE]),// -1 always fetch contract, + // 0 never expired, + // > 0 then compare the timestamp with the current one to see if we need to get contract again + // useful during development + keepContract: createConfig$1(true, [BOOLEAN_TYPE]), + exposeContract: createConfig$1(false, [BOOLEAN_TYPE]), + // @1.2.1 new option for the contract-console to fetch the contract with description + showContractDesc: createConfig$1(false, [BOOLEAN_TYPE]), + contractKey: createConfig$1(false, [BOOLEAN_TYPE]), // if the server side is lock by the key you need this + contractKeyName: createConfig$1(CONTRACT_KEY_NAME, [STRING_TYPE]), // same as above they go in pairs + enableTimeout: createConfig$1(false, [BOOLEAN_TYPE]), // @TODO + timeout: createConfig$1(5000, [NUMBER_TYPE]), // 5 seconds + returnInstance: createConfig$1(false, [BOOLEAN_TYPE]), + allowReturnRawToken: createConfig$1(false, [BOOLEAN_TYPE]), + debugOn: createConfig$1(false, [BOOLEAN_TYPE]) + }; + + // This is for the sync version therefore we don't need to care about the contract options + + function checkOptions(config) { + return checkConfig$1(config, appProps$1, constProps) + } + + var NB_EVENT_SERVICE_PRIVATE_STORE = new WeakMap(); + var NB_EVENT_SERVICE_PRIVATE_LAZY = new WeakMap(); + + /** + * generate a 32bit hash based on the function.toString() + * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery + * @param {string} s the converted to string function + * @return {string} the hashed function string + */ + function hashCode(s) { + return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0) + } + + // making all the functionality on it's own + // import { WatchClass } from './watch' + + var SuspendClass = function SuspendClass() { + // suspend, release and queue + this.__suspend__ = null; + this.queueStore = new Set(); + /* + this.watch('suspend', function(value, prop, oldValue) { + this.logger(`${prop} set from ${oldValue} to ${value}`) + // it means it set the suspend = true then release it + if (oldValue === true && value === false) { + // we want this happen after the return happens + setTimeout(() => { + this.release() + }, 1) + } + return value; // we need to return the value to store it + }) + */ + }; + + var prototypeAccessors$1 = { $suspend: { configurable: true },$queues: { configurable: true } }; + + /** + * setter to set the suspend and check if it's boolean value + * @param {boolean} value to trigger + */ + prototypeAccessors$1.$suspend.set = function (value) { + var this$1 = this; + + if (typeof value === 'boolean') { + var lastValue = this.__suspend__; + this.__suspend__ = value; + this.logger('($suspend)', ("Change from " + lastValue + " --> " + value)); + if (lastValue === true && value === false) { + setTimeout(function () { + this$1.release(); + }, 1); + } + } else { + throw new Error("$suspend only accept Boolean value!") + } + }; + + /** + * queuing call up when it's in suspend mode + * @param {any} value + * @return {Boolean} true when added or false when it's not + */ + SuspendClass.prototype.$queue = function $queue () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + if (this.__suspend__ === true) { + this.logger('($queue)', 'added to $queue', args); + // there shouldn't be any duplicate ... + this.queueStore.add(args); + } + return this.__suspend__; + }; + + /** + * a getter to get all the store queue + * @return {array} Set turn into Array before return + */ + prototypeAccessors$1.$queues.get = function () { + var size = this.queueStore.size; + this.logger('($queues)', ("size: " + size)); + if (size > 0) { + return Array.from(this.queueStore) + } + return [] + }; + + /** + * Release the queue + * @return {int} size if any + */ + SuspendClass.prototype.release = function release () { + var this$1 = this; + + var size = this.queueStore.size; + this.logger('(release)', ("Release was called " + size)); + if (size > 0) { + var queue = Array.from(this.queueStore); + this.queueStore.clear(); + this.logger('queue', queue); + queue.forEach(function (args) { + this$1.logger(args); + Reflect.apply(this$1.$trigger, this$1, args); + }); + this.logger(("Release size " + (this.queueStore.size))); + } + }; + + Object.defineProperties( SuspendClass.prototype, prototypeAccessors$1 ); + + // break up the main file because its getting way too long + + var NbEventServiceBase = /*@__PURE__*/(function (SuspendClass) { + function NbEventServiceBase(config) { + if ( config === void 0 ) config = {}; + + SuspendClass.call(this); + if (config.logger && typeof config.logger === 'function') { + this.logger = config.logger; + } + this.keep = config.keep; + // for the $done setter + this.result = config.keep ? [] : null; + // we need to init the store first otherwise it could be a lot of checking later + this.normalStore = new Map(); + this.lazyStore = new Map(); + } + + if ( SuspendClass ) NbEventServiceBase.__proto__ = SuspendClass; + NbEventServiceBase.prototype = Object.create( SuspendClass && SuspendClass.prototype ); + NbEventServiceBase.prototype.constructor = NbEventServiceBase; + + var prototypeAccessors = { normalStore: { configurable: true },lazyStore: { configurable: true } }; + + /** + * validate the event name(s) + * @param {string[]} evt event name + * @return {boolean} true when OK + */ + NbEventServiceBase.prototype.validateEvt = function validateEvt () { + var this$1 = this; + var evt = [], len = arguments.length; + while ( len-- ) evt[ len ] = arguments[ len ]; + + evt.forEach(function (e) { + if (typeof e !== 'string') { + this$1.logger('(validateEvt)', e); + throw new Error("event name must be string type!") + } + }); + return true; + }; + + /** + * Simple quick check on the two main parameters + * @param {string} evt event name + * @param {function} callback function to call + * @return {boolean} true when OK + */ + NbEventServiceBase.prototype.validate = function validate (evt, callback) { + if (this.validateEvt(evt)) { + if (typeof callback === 'function') { + return true; + } + } + throw new Error("callback required to be function type!") + }; + + /** + * Check if this type is correct or not added in V1.5.0 + * @param {string} type for checking + * @return {boolean} true on OK + */ + NbEventServiceBase.prototype.validateType = function validateType (type) { + var types = ['on', 'only', 'once', 'onlyOnce']; + return !!types.filter(function (t) { return type === t; }).length; + }; + + /** + * Run the callback + * @param {function} callback function to execute + * @param {array} payload for callback + * @param {object} ctx context or null + * @return {void} the result store in $done + */ + NbEventServiceBase.prototype.run = function run (callback, payload, ctx) { + this.logger('(run)', callback, payload, ctx); + this.$done = Reflect.apply(callback, ctx, this.toArray(payload)); + }; + + /** + * Take the content out and remove it from store id by the name + * @param {string} evt event name + * @param {string} [storeName = lazyStore] name of store + * @return {object|boolean} content or false on not found + */ + NbEventServiceBase.prototype.takeFromStore = function takeFromStore (evt, storeName) { + if ( storeName === void 0 ) storeName = 'lazyStore'; + + var store = this[storeName]; // it could be empty at this point + if (store) { + this.logger('(takeFromStore)', storeName, store); + if (store.has(evt)) { + var content = store.get(evt); + this.logger('(takeFromStore)', ("has " + evt), content); + store.delete(evt); + return content; + } + return false; + } + throw new Error((storeName + " is not supported!")) + }; + + /** + * The add to store step is similar so make it generic for resuse + * @param {object} store which store to use + * @param {string} evt event name + * @param {spread} args because the lazy store and normal store store different things + * @return {array} store and the size of the store + */ + NbEventServiceBase.prototype.addToStore = function addToStore (store, evt) { + var args = [], len = arguments.length - 2; + while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ]; + + var fnSet; + if (store.has(evt)) { + this.logger('(addToStore)', (evt + " existed")); + fnSet = store.get(evt); + } else { + this.logger('(addToStore)', ("create new Set for " + evt)); + // this is new + fnSet = new Set(); + } + // lazy only store 2 items - this is not the case in V1.6.0 anymore + // we need to check the first parameter is string or not + if (args.length > 2) { + if (Array.isArray(args[0])) { // lazy store + // check if this type of this event already register in the lazy store + var t = args[2]; + if (!this.checkTypeInLazyStore(evt, t)) { + fnSet.add(args); + } + } else { + if (!this.checkContentExist(args, fnSet)) { + this.logger('(addToStore)', "insert new", args); + fnSet.add(args); + } + } + } else { // add straight to lazy store + fnSet.add(args); + } + store.set(evt, fnSet); + return [store, fnSet.size] + }; + + /** + * @param {array} args for compare + * @param {object} fnSet A Set to search from + * @return {boolean} true on exist + */ + NbEventServiceBase.prototype.checkContentExist = function checkContentExist (args, fnSet) { + var list = Array.from(fnSet); + return !!list.filter(function (l) { + var hash = l[0]; + if (hash === args[0]) { + return true; + } + return false; + }).length; + }; + + /** + * get the existing type to make sure no mix type add to the same store + * @param {string} evtName event name + * @param {string} type the type to check + * @return {boolean} true you can add, false then you can't add this type + */ + NbEventServiceBase.prototype.checkTypeInStore = function checkTypeInStore (evtName, type) { + this.validateEvt(evtName, type); + var all = this.$get(evtName, true); + if (all === false) { + // pristine it means you can add + return true; + } + // it should only have ONE type in ONE event store + return !all.filter(function (list) { + var t = list[3]; + return type !== t; + }).length; + }; + + /** + * This is checking just the lazy store because the structure is different + * therefore we need to use a new method to check it + */ + NbEventServiceBase.prototype.checkTypeInLazyStore = function checkTypeInLazyStore (evtName, type) { + this.validateEvt(evtName, type); + var store = this.lazyStore.get(evtName); + this.logger('(checkTypeInLazyStore)', store); + if (store) { + return !!Array + .from(store) + .filter(function (l) { + var t = l[2]; + return t !== type; + }).length + } + return false; + }; + + /** + * wrapper to re-use the addToStore, + * V1.3.0 add extra check to see if this type can add to this evt + * @param {string} evt event name + * @param {string} type on or once + * @param {function} callback function + * @param {object} context the context the function execute in or null + * @return {number} size of the store + */ + NbEventServiceBase.prototype.addToNormalStore = function addToNormalStore (evt, type, callback, context) { + if ( context === void 0 ) context = null; + + this.logger('(addToNormalStore)', evt, type, 'try to add to normal store'); + // @TODO we need to check the existing store for the type first! + if (this.checkTypeInStore(evt, type)) { + this.logger('(addToNormalStore)', (type + " can add to " + evt + " normal store")); + var key = this.hashFnToKey(callback); + var args = [this.normalStore, evt, key, callback, context, type]; + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.normalStore = _store; + return size; + } + return false; + }; + + /** + * Add to lazy store this get calls when the callback is not register yet + * so we only get a payload object or even nothing + * @param {string} evt event name + * @param {array} payload of arguments or empty if there is none + * @param {object} [context=null] the context the callback execute in + * @param {string} [type=false] register a type so no other type can add to this evt + * @return {number} size of the store + */ + NbEventServiceBase.prototype.addToLazyStore = function addToLazyStore (evt, payload, context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + // this is add in V1.6.0 + // when there is type then we will need to check if this already added in lazy store + // and no other type can add to this lazy store + var args = [this.lazyStore, evt, this.toArray(payload), context]; + if (type) { + args.push(type); + } + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.lazyStore = _store; + return size; + }; + + /** + * make sure we store the argument correctly + * @param {*} arg could be array + * @return {array} make sured + */ + NbEventServiceBase.prototype.toArray = function toArray (arg) { + return Array.isArray(arg) ? arg : [arg]; + }; + + /** + * setter to store the Set in private + * @param {object} obj a Set + */ + prototypeAccessors.normalStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj); + }; + + /** + * @return {object} Set object + */ + prototypeAccessors.normalStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_STORE.get(this) + }; + + /** + * setter to store the Set in lazy store + * @param {object} obj a Set + */ + prototypeAccessors.lazyStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj); + }; + + /** + * @return {object} the lazy store Set + */ + prototypeAccessors.lazyStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this) + }; + + /** + * generate a hashKey to identify the function call + * The build-in store some how could store the same values! + * @param {function} fn the converted to string function + * @return {string} hashKey + */ + NbEventServiceBase.prototype.hashFnToKey = function hashFnToKey (fn) { + return hashCode(fn.toString()) + ''; + }; + + Object.defineProperties( NbEventServiceBase.prototype, prototypeAccessors ); + + return NbEventServiceBase; + }(SuspendClass)); + + // The top level + // export + var EventService = /*@__PURE__*/(function (NbStoreService) { + function EventService(config) { + if ( config === void 0 ) config = {}; + + NbStoreService.call(this, config); + } + + if ( NbStoreService ) EventService.__proto__ = NbStoreService; + EventService.prototype = Object.create( NbStoreService && NbStoreService.prototype ); + EventService.prototype.constructor = EventService; + + var prototypeAccessors = { $done: { configurable: true } }; + + /** + * logger function for overwrite + */ + EventService.prototype.logger = function logger () {}; + + ////////////////////////// + // PUBLIC METHODS // + ////////////////////////// + + /** + * Register your evt handler, note we don't check the type here, + * we expect you to be sensible and know what you are doing. + * @param {string} evt name of event + * @param {function} callback bind method --> if it's array or not + * @param {object} [context=null] to execute this call in + * @return {number} the size of the store + */ + EventService.prototype.$on = function $on (evt , callback , context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + var type = 'on'; + this.validate(evt, callback); + // first need to check if this evt is in lazy store + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register first then call later + if (lazyStoreContent === false) { + this.logger('($on)', (evt + " callback is not in lazy store")); + // @TODO we need to check if there was other listener to this + // event and are they the same type then we could solve that + // register the different type to the same event name + + return this.addToNormalStore(evt, type, callback, context) + } + this.logger('($on)', (evt + " found in lazy store")); + // this is when they call $trigger before register this callback + var size = 0; + lazyStoreContent.forEach(function (content) { + var payload = content[0]; + var ctx = content[1]; + var t = content[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + size += this$1.addToNormalStore(evt, type, callback, context || ctx); + }); + return size; + }; + + /** + * once only registered it once, there is no overwrite option here + * @NOTE change in v1.3.0 $once can add multiple listeners + * but once the event fired, it will remove this event (see $only) + * @param {string} evt name + * @param {function} callback to execute + * @param {object} [context=null] the handler execute in + * @return {boolean} result + */ + EventService.prototype.$once = function $once (evt , callback , context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'once'; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (lazyStoreContent === false) { + this.logger('($once)', (evt + " not in the lazy store")); + // v1.3.0 $once now allow to add multiple listeners + return this.addToNormalStore(evt, type, callback, context) + } else { + // now this is the tricky bit + // there is a potential bug here that cause by the developer + // if they call $trigger first, the lazy won't know it's a once call + // so if in the middle they register any call with the same evt name + // then this $once call will be fucked - add this to the documentation + this.logger('($once)', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + }; + + /** + * This one event can only bind one callbackback + * @param {string} evt event name + * @param {function} callback event handler + * @param {object} [context=null] the context the event handler execute in + * @return {boolean} true bind for first time, false already existed + */ + EventService.prototype.$only = function $only (evt, callback, context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'only'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("($only)", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('($only)', (evt + " found data in lazy store to execute")); + var list = Array.from(lazyStoreContent); + // $only allow to trigger this multiple time on the single handler + list.forEach( function (l) { + var payload = l[0]; + var ctx = l[1]; + var t = l[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + }); + } + return added; + }; + + /** + * $only + $once this is because I found a very subtile bug when we pass a + * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0 + * @param {string} evt event name + * @param {function} callback to call later + * @param {object} [context=null] exeucte context + * @return {void} + */ + EventService.prototype.$onlyOnce = function $onlyOnce (evt, callback, context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'onlyOnce'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("($onlyOnce)", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('($onlyOnce)', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== 'onlyOnce') { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + return added; + }; + + /** + * This is a shorthand of $off + $on added in V1.5.0 + * @param {string} evt event name + * @param {function} callback to exeucte + * @param {object} [context = null] or pass a string as type + * @param {string} [type=on] what type of method to replace + * @return {} + */ + EventService.prototype.$replace = function $replace (evt, callback, context, type) { + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = 'on'; + + if (this.validateType(type)) { + this.$off(evt); + var method = this['$' + type]; + return Reflect.apply(method, this, [evt, callback, context]) + } + throw new Error((type + " is not supported!")) + }; + + /** + * trigger the event + * @param {string} evt name NOT allow array anymore! + * @param {mixed} [payload = []] pass to fn + * @param {object|string} [context = null] overwrite what stored + * @param {string} [type=false] if pass this then we need to add type to store too + * @return {number} if it has been execute how many times + */ + EventService.prototype.$trigger = function $trigger (evt , payload , context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + this.validateEvt(evt); + var found = 0; + // first check the normal store + var nStore = this.normalStore; + this.logger('($trigger)', 'normalStore', nStore); + if (nStore.has(evt)) { + // @1.8.0 to add the suspend queue + var added = this.$queue(evt, payload, context, type); + this.logger('($trigger)', evt, 'found; add to queue: ', added); + if (added === true) { + return false; // not executed + } + var nSet = Array.from(nStore.get(evt)); + var ctn = nSet.length; + var hasOnce = false; + for (var i=0; i < ctn; ++i) { + ++found; + // this.logger('found', found) + var ref = nSet[i]; + var _ = ref[0]; + var callback = ref[1]; + var ctx = ref[2]; + var type$1 = ref[3]; + this.run(callback, payload, context || ctx); + if (type$1 === 'once' || type$1 === 'onlyOnce') { + hasOnce = true; + } + } + if (hasOnce) { + nStore.delete(evt); + } + return found; + } + // now this is not register yet + this.addToLazyStore(evt, payload, context, type); + return found; + }; + + /** + * this is an alias to the $trigger + * @NOTE breaking change in V1.6.0 we swap the parameter around + * @param {string} evt event name + * @param {*} params pass to the callback + * @param {string} type of call + * @param {object} context what context callback execute in + * @return {*} from $trigger + */ + EventService.prototype.$call = function $call (evt, params, type, context) { + if ( type === void 0 ) type = false; + if ( context === void 0 ) context = null; + + var args = [evt, params]; + args.push(context, type); + return Reflect.apply(this.$trigger, this, args) + }; + + /** + * remove the evt from all the stores + * @param {string} evt name + * @return {boolean} true actually delete something + */ + EventService.prototype.$off = function $off (evt) { + this.validateEvt(evt); + var stores = [ this.lazyStore, this.normalStore ]; + var found = false; + stores.forEach(function (store) { + if (store.has(evt)) { + found = true; + store.delete(evt); + } + }); + return found; + }; + + /** + * return all the listener from the event + * @param {string} evtName event name + * @param {boolean} [full=false] if true then return the entire content + * @return {array|boolean} listerner(s) or false when not found + */ + EventService.prototype.$get = function $get (evt, full) { + if ( full === void 0 ) full = false; + + this.validateEvt(evt); + var store = this.normalStore; + if (store.has(evt)) { + return Array + .from(store.get(evt)) + .map( function (l) { + if (full) { + return l; + } + var key = l[0]; + var callback = l[1]; + return callback; + }) + } + return false; + }; + + /** + * store the return result from the run + * @param {*} value whatever return from callback + */ + prototypeAccessors.$done.set = function (value) { + this.logger('($done)', 'value: ', value); + if (this.keep) { + this.result.push(value); + } else { + this.result = value; + } + }; + + /** + * @TODO is there any real use with the keep prop? + * getter for $done + * @return {*} whatever last store result + */ + prototypeAccessors.$done.get = function () { + if (this.keep) { + this.logger('(get $done)', this.result); + return this.result[this.result.length - 1] + } + return this.result; + }; + + Object.defineProperties( EventService.prototype, prototypeAccessors ); + + return EventService; + }(NbEventServiceBase)); + + // default + + // this will generate a event emitter and will be use everywhere + // output + function getEventEmitter(debugOn) { + var logger = debugOn ? function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + args.unshift('[NBS]'); + console.log.apply(null, args); + }: undefined; + return new EventService({ logger: logger }) + } + + // this is the new Event base interface + /** + * this is the slim client without Fly, you pick the version of Fly to use + * This is a breaking change because it swap the input positions + * @param {object} Fly fly.js + * @param {object} config configuration + * @return {object} the jsonql client instance + */ + function jsonqlStaticClient(Fly, config) { + if ( config === void 0 ) config = {}; + + var contract = config.contract; + var opts = checkOptions(config); + var jsonqlBase = new JsonqlBaseClient(opts, Fly); + var contractPromise = getContractFromConfig(jsonqlBase, contract); + var ee = getEventEmitter(opts.debugOn); + // finally + var methods = generator(jsonqlBase, opts, contractPromise, ee); + methods.eventEmitter = ee; + return methods; + } + + // This is the static version that build with the Fly for Browser + + // this is the slim client without Fly + function jsonqlStaticClientFull(config) { + if ( config === void 0 ) config = {}; + + return jsonqlStaticClient(Fly$1, config) + } + + return jsonqlStaticClientFull; + +})); +//# sourceMappingURL=jsonql-client.static.js.map diff --git a/packages/@jsonql/client/dist/jsonql-client.static.js.map b/packages/@jsonql/client/dist/jsonql-client.static.js.map new file mode 100644 index 0000000000000000000000000000000000000000..dc1e747ef11b12351c39b6bafe6d7dbe42a0de51 --- /dev/null +++ b/packages/@jsonql/client/dist/jsonql-client.static.js.map @@ -0,0 +1 @@ +{"version":3,"file":"jsonql-client.static.js","sources":["../node_modules/lodash-es/isNull.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/negate.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/error-base.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/log.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-sync.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/index.js","../src/core/methods-generator.js","../src/utils.js","../src/core/jsonql-static-generator.js","../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/stores/local-store.js","../src/stores/session-store.js","../src/stores/index.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/node_modules/jsonql-utils/src/generic.js","../node_modules/jsonql-jwt/node_modules/jsonql-utils/src/koa.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../src/base/http-cls.js","../src/base/contract-cls.js","../src/base/auth-cls.js","../src/base/base-cls.js","../src/base/index.js","../src/options/base-options.js","../src/options/check-options.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/suspend.js","../node_modules/nb-event-service/src/store-service.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/ee.js","../src/static.js","../src/static-full.js"],"sourcesContent":["/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from './lodash'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from './lodash'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from './lodash'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from './lodash'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\n\nimport { isNull, trim, isUndefined } from './lodash'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from './lodash'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from './lodash'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// The base Error of all\nimport whereAmI from './where-am-i'\n\nexport default class JsonqlBaseError extends Error {\n constructor(...args) {\n super(...args)\n }\n\n static where() {\n return whereAmI()\n }\n \n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\nimport JsonqlBaseError from './error-base'\n// when validaton failed\nexport default class JsonqlValidationError extends JsonqlBaseError {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj)\n return !!keys.filter(k => key === k).length;\n}\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail)\n }\n throw new JsonqlError(msg, detail)\n }\n // pass through to the next\n return result;\n}\n","/**\n * just a simple util for helping to debug\n * @param {array} args arguments\n * @return {void}\n */\nexport default function log(...args) {\n try {\n if (window && window.console) {\n Reflect.apply(console.log, console, args)\n }\n } catch(e) {}\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from './lodash'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\nimport log from './log'\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n log(1)\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ))\n case params[0].variable === true: // using spread syntax\n log(2)\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ))\n // with optional defaultValue parameters\n case args.length < params.length:\n log(3)\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ))\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length:\n log(4)\n let ctn = params.length;\n // this happens when we have those array. type\n let _type = [ DEFAULT_TYPE ]\n // we only looking at the first one, this might be a @BUG\n /*\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n } */\n // if we use the params as guide then the rest will get throw out\n // which is not what we want, instead, anything without the param\n // will get a any type and optional flag\n return args.map((arg, i) => {\n let optional = i >= ctn ? true : !!params[i].optional\n let param = params[i] || { type: _type, name: `_${i}` }\n return {\n arg: optional ? getOptionalValue(arg, param) : arg,\n index: i,\n param,\n optional\n }\n })\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n log(5)\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n // v1.4.4 this fixed the problem, the root level optional is from the last fn\n if (p.optional === true || p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from '../lodash'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport log from '../log'\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n log('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n log(ENUM_KEY, value[ENUM_KEY])\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n log(CHECKER_KEY, value[CHECKER_KEY])\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","// this is port back from the client to share across all projects\nimport { merge } from '../lodash'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return merge(\n runValidation(\n prepareArgsForValidation(config, appProps),\n cb\n ),\n constProps\n )\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport { isFunction, isString } from '../lodash'\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants'\n\nimport { checkIsArray } from '../array'\nimport checkIsBoolean from '../boolean'\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n}\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\n// export the two extra functions\nimport isInArray from './src/is-in-array'\nimport isKeyInObjectFn from './src/is-key-in-object'\n\nexport const inArray = isInArray;\nexport const isKeyInObject = isKeyInObjectFn;\n","// breaking out the inner methods generator in here\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * Here just generate the methods calls\n * @param {object} jsonqlInstance what it said\n * @param {object} ee event emitter\n * @param {object} config configuration\n * @param {object} contract the map\n * @return {object} with mapped methods\n */\nexport default function methodsGenerator(jsonqlInstance, ee, config, contract) {\n let obj = {query: {}, mutation: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n obj.auth = {} // v1.3.1 add back the auth prop name\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj.auth[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.$trigger(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj.auth[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.$trigger(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj.auth[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.$trigger(LOGOUT_NAME, KEY_WORD)\n }\n }\n }\n return obj;\n}\n","// take only the module part which is what we use here\n// and export it again to use through out the client\n// this way we avoid those that we don't want node.js module got build into the code\nimport {\n createEvt,\n\n createQuery,\n createMutation,\n getNameFromPayload,\n cacheBurst,\n urlParams,\n resultHandler,\n\n isContract,\n timestamp,\n inArray\n} from './jsonql-utils' // this should point to the module.js\n/**\n * @param {object} jsonqlInstance the init instance of jsonql client\n * @param {object} contract the static contract\n * @return {object} contract may be from server\n */\nconst getContractFromConfig = function(jsonqlInstance, contract = {}) {\n if (isContract(contract)) {\n return Promise.resolve(contract)\n }\n return jsonqlInstance.getContract()\n}\n\n// export some constants as well\n// since it's only use here there is no point of adding it to the constants module\n// or may be we add it back later\nconst ENDPOINT_TABLE = 'endpoint';\nconst USERDATA_TABLE = 'userdata';\n\n// export\nexport {\n getContractFromConfig,\n ENDPOINT_TABLE,\n USERDATA_TABLE,\n createEvt,\n\n createQuery,\n createMutation,\n getNameFromPayload,\n cacheBurst,\n urlParams,\n resultHandler,\n\n isContract,\n timestamp,\n inArray\n}\n","// This generator will use the old style\n// with default methods\nimport { RESULT_PROP_NAME, ERROR_PROP_NAME } from 'jsonql-constants'\n\nimport methodsGenerator from './methods-generator'\nimport { createEvt } from '../utils'\n\n\n/**\n * Group all the same methods together\n * @param {object} ee event emitter\n * @param {string} type query, mutation or auth\n * @param {string} resolverName use as the guide\n * @param {array} args from the call\n * @return {function} the handler itself\n */\nconst handler = (ee, type) => {\n // we don't run validate here because we want until the contract is ready\n return (resolverName, ...args) => (\n new Promise((resolver, rejecter) => {\n // this are the callbacks\n ee.$only(createEvt(type, resolverName, RESULT_PROP_NAME), resolver)\n ee.$only(createEvt(type, resolverName, ERROR_PROP_NAME), rejecter)\n // this is the main call\n ee.$trigger(type, { resolverName, args })\n })\n )\n}\n\n/**\n * @param {object} ee eventEmitter\n * @param {object} contract the map\n * @param {object} config configuration\n */\nconst validateRegisteredEvents = (ee, contract, config) => {\n const storedEvt = ee.$queues;\n const debug = config.debugOn;\n if (debug) {\n console.info('(validateRegisteredEvents)', 'storedEvt', storedEvt)\n }\n storedEvt.forEach(args => {\n let [type, payload] = args;\n let { resolverName } = payload;\n if (debug) {\n console.info('(validateRegisteredEvents)', type, resolverName)\n }\n if (!contract[type][resolverName]) {\n throw new Error(`${type}.${resolverName} not existed in contract!`)\n }\n })\n}\n\n/**\n * set up all the event handlers once the contract is ready\n * @param {object} jsonqlInstance what the name said\n * @param {object} ee event emitter\n * @param {object} config the configuration\n * @param {object} contract the map\n * @return {void} nothing\n */\nfunction setupEventHandlers(jsonqlInstance, ee, config, contract) {\n let methods = methodsGenerator(jsonqlInstance, ee, config, contract)\n validateRegisteredEvents(ee, contract, config)\n // create handler\n for (let type in methods) {\n // setup event listeners - only one listener per type\n ee.$only(type, function({resolverName, args}) {\n if (methods[type][resolverName]) {\n Reflect.apply(methods[type][resolverName], null, args)\n .then(result => {\n ee.$trigger(createEvt(type, resolverName, RESULT_PROP_NAME), result)\n })\n .catch(err => {\n ee.$trigger(createEvt(type, resolverName, ERROR_PROP_NAME), err)\n })\n } else {\n console.error(`${resolverName} is not defined in the contract!`)\n }\n })\n }\n // all done now release the queue if any\n setTimeout(() => {\n ee.$suspend = false;\n }, 1)\n}\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contractPromise an unresolve promise\n * @param {object} ee eventEmitter\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contractPromise, ee) => {\n ee.$suspend = true; // hold all the calls\n // wait for the promise to resolve\n contractPromise.then(contract => {\n setupEventHandlers(jsonqlInstance, ee, config, contract)\n })\n // construct the api\n let obj = {\n query: handler(ee, 'query'),\n mutation: handler(ee, 'mutation'),\n auth: handler(ee, 'auth')\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n // obj.eventEmitter = ee;\n // this will require a param\n if (config.exposeContract) {\n obj.getContract = () => jsonqlInstance.get()\n }\n if (config.enableAuth) {\n obj.userdata = () => jsonqlInstance.userdata;\n }\n obj.version = '__VERSION__';\n // output\n return obj;\n}\n\nexport default generator;\n","module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// bunch of generic helpers\nimport debug from 'debug'\nimport { isArray, isPlainObject, trim } from 'lodash-es'\n\n/**\n * @param {string} name the name part after the :\n * @param {string} baseName the base before the :\n */\nexport const getDebug = (name, baseName = 'jsonql') => {\n return debug(baseName).extend(name)\n}\n\n/**\n * DIY in Array\n * @param {array} arr to check from\n * @param {*} value to check against\n * @return {boolean} true on found\n */\nexport const inArray = (arr, value) => !!arr.filter(a => a === value).length;\n\n// quick and dirty to turn non array to array\nexport const toArray = (arg) => isArray(arg) ? arg : [arg];\n\n/**\n * @param {object} obj for search\n * @param {string} key target\n * @return {boolean} true on success\n */\nexport const isKeyInObject = function(obj, key) {\n const keys = Object.keys(obj)\n return inArray(keys, key)\n}\n\n/**\n * create a event name\n * @param {string[]} args\n * @return {string} event name for use\n */\nexport const createEvt = (...args) => args.join('_')\n\n/**\n * @param {boolean} sec return in second or not\n * @return {number} timestamp\n */\nexport const timestamp = (sec = false) => {\n let time = Date.now()\n return sec ? Math.floor( time / 1000 ) : time;\n}\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * construct a url with cache burster\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\n/**\n * @return {object} _cb as key with timestamp\n */\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * From underscore.string library\n * @BUG there is a bug here with the non-standard name start with _\n * @param {string} str string\n * @return {string} dasherize string\n */\nexport const dasherize = str => (\n trim(str)\n .replace(/([A-Z])/g, '-$1')\n .replace(/[-_\\s]+/g, '-')\n .toLowerCase()\n)\n\n/**\n * simple util method to get the value\n * @param {string} name of the key\n * @param {object} obj to take value from\n * @return {*} the object value id by name or undefined\n */\nexport const getConfigValue = (name, obj) => (\n obj && isPlainObject(obj) ? ( (name in obj) ? obj[name] : undefined ) : undefined\n)\n\n/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nexport const isNotEmpty = function(param) {\n return param !== undefined && param !== false && param !== null && trim(param) !== '';\n}\n","// koa specific methods\nimport {\n CONTENT_TYPE,\n SUCCESS_STATUS,\n FORBIDDEN_STATUS\n} from 'jsonql-constants'\n// fix the default is not export by module error\nimport * as jsonqlErrors from 'jsonql-errors'\nimport {\n getDocLen,\n headerParser,\n isHeaderPresent,\n getCallMethod,\n getPathToFn,\n packResult,\n packError\n} from './middleware'\nimport { dasherize, getDebug } from './generic'\nconst debug = getDebug(`koa`, `jsonql-utils`)\n/**\n * @TODO need to be more flexible\n * @param {object} ctx koa\n * @param {object} opts configuration\n * @return {boolean} if it match\n */\nexport const isJsonqlPath = (ctx, opts) => ctx.path === opts.jsonqlPath;\n\n/**\n * combine two check in one and save time\n * @param {object} ctx koa\n * @param {object} opts config\n * @return {boolean} check result\n */\nexport const isJsonqlRequest = (ctx, opts) => {\n const header = isHeaderPresent(ctx.request, opts.contentType)\n if (header) {\n return isJsonqlPath(ctx, opts)\n }\n return false;\n}\n\n/**\n * check if this is point to the jsonql console\n * @param {object} ctx koa context\n * @param {object} opts config\n * @return {boolean}\n */\nexport const isJsonqlConsoleUrl = (ctx, opts) => (\n ctx.method === 'GET' && isJsonqlPath(ctx, opts)\n)\n\n/**\n * Handle the output\n * @param {object} opts configuration\n * @return {function} with ctx and body as params\n */\nexport const handleOutput = function(opts) {\n return function(ctx, body) {\n ctx.size = getDocLen(body)\n ctx.type = opts.contentType;\n ctx.status = SUCCESS_STATUS;\n ctx.body = body;\n }\n}\n\n/**\n * handle HTML output for the web console\n * @param {object} ctx koa context\n * @param {string} body output content\n * @return {void}\n */\nexport const handleHtmlOutput = function(ctx, body) {\n ctx.size = getDocLen(body)\n ctx.type = 'text/html';\n ctx.status = SUCCESS_STATUS;\n ctx.body = body + ''; // just make sure its string output\n}\n\n/**\n * use the ctx to generate error output\n * V1.1.0 we render this as a normal output with status 200\n * then on the client side will check against the result object for error\n * @param {object} ctx context\n * @param {number} code 404 / 500 etc\n * @param {object} e actual error\n * @param {string} message if there is one\n * @param {string} name custom error class name\n */\nexport const ctxErrorHandler = function(ctx, code, e, message = '') {\n const render = handleOutput({contentType: CONTENT_TYPE})\n debug('[ctxErrorHandler]', code, e, message)\n let name;\n if (typeof code === 'string') {\n name = code;\n code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1;\n } else {\n debug(`[ctxErrorHandler] using getErrorByStatus`)\n name = jsonqlErrors.getErrorByStatus(code)\n }\n debug(`[ctxErrorHandler.name]`, name)\n // preserve the message\n if (!message && e && e.message) {\n message = e.message;\n }\n return render(ctx, packError(e, name, code, message))\n}\n\n/**\n * Just a wrapper to be clearer what error is it\n * @param {object} ctx koa\n * @param {object} e error\n * @return {undefined} nothing\n */\nexport const forbiddenHandler = (ctx, e) => (\n ctxErrorHandler(ctx, FORBIDDEN_STATUS, e, 'JsonqlAuthorisationError')\n)\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\nimport { timestamp } from 'jsonql-utils'\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || timestamp()\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// base HttpClass\nimport merge from 'lodash-es/merge'\nimport {\n createQuery,\n createMutation,\n getNameFromPayload,\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n isObject,\n isString\n} from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME,\n SHOW_CONTRACT_DESC_PARAM\n} from 'jsonql-constants'\n\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nconst _log = (...args) => {\n try {\n if (window && window.console) {\n Reflect.apply(console.log, null, args)\n }\n } catch(e) {}\n}\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n // change the way how we init Fly\n // flyio now become external depedencies and it makes it easier to switch\n // @BUG should we run test to check if we have the windows object?\n _log(opts)\n this.fly = opts.Fly ? new opts.Fly() : new Fly()\n // to a different environment like WeChat mini app\n this.opts = opts;\n this.extraHeader = {};\n // @1.2.1 for adding query to the call on the fly\n this.extraParams = {};\n // this.log('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = merge({}, cacheBurst(), this.extraParams)\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, { method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n const headers = this.getHeaders();\n this.log('request interceptor call', headers)\n\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n this.log('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n this.extraParams = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n if (this.opts.showContractDesc) {\n this.extraParams = merge({}, this.extraParams, SHOW_CONTRACT_DESC_PARAM)\n }\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n this.log('get contract result', result)\n // when refresh the window the result is different!\n // @TODO need to check the Koa side about why is that\n // also it should set a flag if we want the description or not\n if (result.cache && result.contract) {\n return result.contract;\n }\n // just the normal result\n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport { timestamp, isContract, ENDPOINT_TABLE } from '../utils'\nimport { localStore } from '../stores'\n\nimport HttpClass from './http-cls';\n\n// export\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contracts = this.readContract()\n this.log('getContract first call', contracts)\n if (contracts && Array.isArray(contracts)) {\n const contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]\n if (contract) {\n return Promise.resolve(contract)\n }\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isContract(contract)) {\n throw new JsonqlValidationError(`Contract is malformed!`)\n //return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired)\n if (!isNaN(expired) && expired > 0) {\n args.push(expired)\n }\n }\n // calling the setter\n this.jsonqlContract = args;\n // return it\n this.log('storeContract return result', contract)\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts)\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport { localStore, sessionStore } from '../stores'\nimport { timestamp, inArray, ENDPOINT_TABLE, USERDATA_TABLE } from '../utils'\n\nimport AuthCls from './auth-cls'\n\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts, Fly = null) {\n if (Fly) {\n opts.Fly = Fly;\n }\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n console.info('storeIt', args)\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey;\n let _args = [ key ]\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n _args.push(contracts)\n if (expired) {\n _args.push(expired)\n }\n if (this.opts.keepContract) {\n this.storeIt = _args;\n }\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n\n /**\n * this one will use the sessionStore\n * basically we hook this onto the token store and decode it to store here\n */\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n /**\n * This also manage the index internally\n * There is NO need to store them in an array\n * because each instance contain one end point\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n\n /**\n * this one store in the session store\n * get login userdata decoded jwt\n * @return {object|null}\n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n /**\n * simple log\n */\n log(...args) {\n if (this.opts.debugOn === true) {\n Reflect.apply(console.info, console, args)\n }\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","// all the client configuration options here\nimport {\n JSONQL_PATH,\n CONTENT_TYPE,\n BEARER,\n CLIENT_STORAGE_KEY,\n CLIENT_AUTH_KEY,\n CONTRACT_KEY_NAME,\n AUTH_HEADER,\n ISSUER_NAME,\n LOGOUT_NAME,\n BOOLEAN_TYPE,\n STRING_TYPE,\n NUMBER_TYPE,\n DEFAULT_HEADER\n} from 'jsonql-constants'\nimport { createConfig } from 'jsonql-params-validator'\nexport const constProps = {\n contract: false,\n MUTATION_ARGS: ['name', 'payload', 'conditions'], // this seems wrong?\n CONTENT_TYPE,\n BEARER,\n AUTH_HEADER\n}\n\n// grab the localhost name and put into the hostname as default\nconst getHostName = () => (\n [window.location.protocol, window.location.host].join('//')\n)\n\nexport const appProps = {\n\n hostname: createConfig(getHostName(), [STRING_TYPE]), // required the hostname\n jsonqlPath: createConfig(JSONQL_PATH, [STRING_TYPE]), // The path on the server\n\n loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]),\n logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]),\n // add to koa v1.3.0 - this might remove in the future\n enableJsonp: createConfig(false, [BOOLEAN_TYPE]),\n enableAuth: createConfig(false, [BOOLEAN_TYPE]),\n // enable useJwt by default\n useJwt: createConfig(true, [BOOLEAN_TYPE]),\n\n // the header\n // v1.2.0 we are using this option during the dev\n // so it won't save anything to the localstorage and fetch a new contract\n // whenever the browser reload\n useLocalstorage: createConfig(true, [BOOLEAN_TYPE]), // should we store the contract into localStorage\n storageKey: createConfig(CLIENT_STORAGE_KEY, [STRING_TYPE]),// the key to use when store into localStorage\n authKey: createConfig(CLIENT_AUTH_KEY, [STRING_TYPE]),// the key to use when store into the sessionStorage\n contractExpired: createConfig(0, [NUMBER_TYPE]),// -1 always fetch contract,\n // 0 never expired,\n // > 0 then compare the timestamp with the current one to see if we need to get contract again\n // useful during development\n keepContract: createConfig(true, [BOOLEAN_TYPE]),\n exposeContract: createConfig(false, [BOOLEAN_TYPE]),\n // @1.2.1 new option for the contract-console to fetch the contract with description\n showContractDesc: createConfig(false, [BOOLEAN_TYPE]),\n contractKey: createConfig(false, [BOOLEAN_TYPE]), // if the server side is lock by the key you need this\n contractKeyName: createConfig(CONTRACT_KEY_NAME, [STRING_TYPE]), // same as above they go in pairs\n enableTimeout: createConfig(false, [BOOLEAN_TYPE]), // @TODO\n timeout: createConfig(5000, [NUMBER_TYPE]), // 5 seconds\n returnInstance: createConfig(false, [BOOLEAN_TYPE]),\n allowReturnRawToken: createConfig(false, [BOOLEAN_TYPE]),\n debugOn: createConfig(false, [BOOLEAN_TYPE])\n}\n","// This is for the sync version therefore we don't need to care about the contract options\nimport { appProps, constProps } from './base-options'\nimport { checkConfig } from 'jsonql-params-validator'\n\nexport default function checkOptions(config) {\n return checkConfig(config, appProps, constProps)\n}\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// making all the functionality on it's own\n// import { WatchClass } from './watch'\n\nexport default class SuspendClass {\n\n constructor() {\n // suspend, release and queue\n this.__suspend__ = null;\n this.queueStore = new Set()\n /*\n this.watch('suspend', function(value, prop, oldValue) {\n this.logger(`${prop} set from ${oldValue} to ${value}`)\n // it means it set the suspend = true then release it\n if (oldValue === true && value === false) {\n // we want this happen after the return happens\n setTimeout(() => {\n this.release()\n }, 1)\n }\n return value; // we need to return the value to store it\n })\n */\n }\n\n /**\n * setter to set the suspend and check if it's boolean value\n * @param {boolean} value to trigger\n */\n set $suspend(value) {\n if (typeof value === 'boolean') {\n const lastValue = this.__suspend__;\n this.__suspend__ = value;\n this.logger('($suspend)', `Change from ${lastValue} --> ${value}`)\n if (lastValue === true && value === false) {\n setTimeout(() => {\n this.release()\n }, 1)\n }\n } else {\n throw new Error(`$suspend only accept Boolean value!`)\n }\n }\n\n /**\n * queuing call up when it's in suspend mode\n * @param {any} value\n * @return {Boolean} true when added or false when it's not\n */\n $queue(...args) {\n if (this.__suspend__ === true) {\n this.logger('($queue)', 'added to $queue', args)\n // there shouldn't be any duplicate ...\n this.queueStore.add(args)\n }\n return this.__suspend__;\n }\n\n /**\n * a getter to get all the store queue\n * @return {array} Set turn into Array before return\n */\n get $queues() {\n let size = this.queueStore.size;\n this.logger('($queues)', `size: ${size}`)\n if (size > 0) {\n return Array.from(this.queueStore)\n }\n return []\n }\n\n /**\n * Release the queue\n * @return {int} size if any\n */\n release() {\n let size = this.queueStore.size\n this.logger('(release)', `Release was called ${size}`)\n if (size > 0) {\n const queue = Array.from(this.queueStore)\n this.queueStore.clear()\n this.logger('queue', queue)\n queue.forEach(args => {\n this.logger(args)\n Reflect.apply(this.$trigger, this, args)\n })\n this.logger(`Release size ${this.queueStore.size}`)\n }\n }\n}\n","// break up the main file because its getting way too long\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code'\nimport SuspendClass from './suspend'\n\nexport default class NbEventServiceBase extends SuspendClass {\n\n constructor(config = {}) {\n super()\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * validate the event name(s)\n * @param {string[]} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(...evt) {\n evt.forEach(e => {\n if (typeof e !== 'string') {\n this.logger('(validateEvt)', e)\n throw new Error(`event name must be string type!`)\n }\n })\n return true;\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('(run)', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('(takeFromStore)', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('(takeFromStore)', `has ${evt}`, content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('(addToStore)', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('(addToStore)', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('(addToStore)', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName, type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName, type)\n let store = this.lazyStore.get(evtName)\n this.logger('(checkTypeInLazyStore)', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('(addToNormalStore)', evt, type, 'try to add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger('(addToNormalStore)', `${type} can add to ${evt} normal store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n}\n","// The top level\nimport NbStoreService from './store-service'\n// export\nexport default class EventService extends NbStoreService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n super(config)\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('($on)', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('($on)', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('($once)', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('($once)', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`($only)`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('($only)', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`($onlyOnce)`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('($onlyOnce)', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('($trigger)', 'normalStore', nStore)\n if (nStore.has(evt)) {\n // @1.8.0 to add the suspend queue\n let added = this.$queue(evt, payload, context, type)\n this.logger('($trigger)', evt, 'found; add to queue: ', added)\n if (added === true) {\n return false; // not executed\n }\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('($done)', 'value: ', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger('(get $done)', this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n// output\nexport default function(debugOn) {\n let logger = debugOn ? (...args) => {\n args.unshift('[NBS]')\n console.log.apply(null, args)\n }: undefined;\n return new NBEventService({ logger })\n}\n","// this is the new Event base interface\n// the export will be different and purposely design for framework that\n// is very hard to use Promise such as Vue\nimport jsonqlStaticGenerator from './core/jsonql-static-generator'\nimport JsonqlBaseClient from './base'\nimport { checkOptions } from './options'\nimport { getContractFromConfig } from './utils'\nimport getEventEmitter from './ee'\n/**\n * this is the slim client without Fly, you pick the version of Fly to use\n * This is a breaking change because it swap the input positions\n * @param {object} Fly fly.js\n * @param {object} config configuration\n * @return {object} the jsonql client instance\n */\nexport default function jsonqlStaticClient(Fly, config = {}) {\n const { contract } = config;\n const opts = checkOptions(config)\n const jsonqlBase = new JsonqlBaseClient(opts, Fly)\n const contractPromise = getContractFromConfig(jsonqlBase, contract)\n const ee = getEventEmitter(opts.debugOn)\n // finally\n let methods = jsonqlStaticGenerator(jsonqlBase, opts, contractPromise, ee)\n methods.eventEmitter = ee;\n return methods;\n}\n","// This is the static version that build with the Fly for Browser\nimport Fly from 'flyio/dist/npm/fly'\nimport jsonqlStaticClient from './static'\n\n// this is the slim client without Fly\nexport default function jsonqlStaticClientFull(config = {}) {\n return jsonqlStaticClient(Fly, config)\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/packages/@jsonql/client/dist/jsonql-client.umd.js b/packages/@jsonql/client/dist/jsonql-client.umd.js new file mode 100644 index 0000000000000000000000000000000000000000..11a8ef75381fd9f15759966929c48329dae21e9e --- /dev/null +++ b/packages/@jsonql/client/dist/jsonql-client.umd.js @@ -0,0 +1,9834 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('debug')) : + typeof define === 'function' && define.amd ? define(['debug'], factory) : + (global = global || self, global.jsonqlClient = factory(global.debug)); +}(this, function (debug$1) { 'use strict'; + + debug$1 = debug$1 && debug$1.hasOwnProperty('default') ? debug$1['default'] : debug$1; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var fly = createCommonjsModule(function (module, exports) { + (function webpackUniversalModuleDefinition(root, factory) { + { module.exports = factory(); } + })(commonjsGlobal, function() { + return /******/ (function(modules) { // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + /******/ + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + /******/ + /******/ // Check if module is in cache + /******/ if(installedModules[moduleId]) { + /******/ return installedModules[moduleId].exports; + /******/ } + /******/ // Create a new module (and put it into the cache) + /******/ var module = installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {} + /******/ }; + /******/ + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ + /******/ // Flag the module as loaded + /******/ module.l = true; + /******/ + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } + /******/ + /******/ + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + /******/ + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + /******/ + /******/ // identity function for calling harmony imports with the correct context + /******/ __webpack_require__.i = function(value) { return value; }; + /******/ + /******/ // define getter function for harmony exports + /******/ __webpack_require__.d = function(exports, name, getter) { + /******/ if(!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { + /******/ configurable: false, + /******/ enumerable: true, + /******/ get: getter + /******/ }); + /******/ } + /******/ }; + /******/ + /******/ // getDefaultExport function for compatibility with non-harmony modules + /******/ __webpack_require__.n = function(module) { + /******/ var getter = module && module.__esModule ? + /******/ function getDefault() { return module['default']; } : + /******/ function getModuleExports() { return module; }; + /******/ __webpack_require__.d(getter, 'a', getter); + /******/ return getter; + /******/ }; + /******/ + /******/ // Object.prototype.hasOwnProperty.call + /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + /******/ + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = ""; + /******/ + /******/ // Load entry module and return exports + /******/ return __webpack_require__(__webpack_require__.s = 2); + /******/ }) + /************************************************************************/ + /******/ ([ + /* 0 */ + /***/ (function(module, exports, __webpack_require__) { + + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + module.exports = { + type: function type(ob) { + return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase(); + }, + isObject: function isObject(ob, real) { + if (real) { + return this.type(ob) === "object"; + } else { + return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object'; + } + }, + isFormData: function isFormData(val) { + return typeof FormData !== 'undefined' && val instanceof FormData; + }, + trim: function trim(str) { + return str.replace(/(^\s*)|(\s*$)/g, ''); + }, + encode: function encode(val) { + return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']'); + }, + formatParams: function formatParams(data) { + var str = ""; + var first = true; + var that = this; + if (!this.isObject(data)) { + return data; + } + + function _encode(sub, path) { + var encode = that.encode; + var type = that.type(sub); + if (type == "array") { + sub.forEach(function (e, i) { + if (!that.isObject(e)) { i = ""; } + _encode(e, path + ('%5B' + i + '%5D')); + }); + } else if (type == "object") { + for (var key in sub) { + if (path) { + _encode(sub[key], path + "%5B" + encode(key) + "%5D"); + } else { + _encode(sub[key], encode(key)); + } + } + } else { + if (!first) { + str += "&"; + } + first = false; + str += path + "=" + encode(sub); + } + } + + _encode(data, ""); + return str; + }, + + // Do not overwrite existing attributes + merge: function merge(a, b) { + for (var key in b) { + if (!a.hasOwnProperty(key)) { + a[key] = b[key]; + } else if (this.isObject(b[key], 1) && this.isObject(a[key], 1)) { + this.merge(a[key], b[key]); + } + } + return a; + } + }; + + /***/ }), + /* 1 */, + /* 2 */ + /***/ (function(module, exports, __webpack_require__) { + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var utils = __webpack_require__(0); + var isBrowser = typeof document !== "undefined"; + + var Fly = function () { + function Fly(engine) { + _classCallCheck(this, Fly); + + this.engine = engine || XMLHttpRequest; + + this.default = this; //For typeScript + + /** + * Add lock/unlock API for interceptor. + * + * Once an request/response interceptor is locked, the incoming request/response + * will be added to a queue before they enter the interceptor, they will not be + * continued until the interceptor is unlocked. + * + * @param [interceptor] either is interceptors.request or interceptors.response + */ + function wrap(interceptor) { + var resolve = void 0; + var reject = void 0; + + function _clear() { + interceptor.p = resolve = reject = null; + } + + utils.merge(interceptor, { + lock: function lock() { + if (!resolve) { + interceptor.p = new Promise(function (_resolve, _reject) { + resolve = _resolve; + reject = _reject; + }); + } + }, + unlock: function unlock() { + if (resolve) { + resolve(); + _clear(); + } + }, + clear: function clear() { + if (reject) { + reject("cancel"); + _clear(); + } + } + }); + } + + var interceptors = this.interceptors = { + response: { + use: function use(handler, onerror) { + this.handler = handler; + this.onerror = onerror; + } + }, + request: { + use: function use(handler) { + this.handler = handler; + } + } + }; + + var irq = interceptors.request; + var irp = interceptors.response; + wrap(irp); + wrap(irq); + + this.config = { + method: "GET", + baseURL: "", + headers: {}, + timeout: 0, + params: {}, // Default Url params + parseJson: true, // Convert response data to JSON object automatically. + withCredentials: false + }; + } + + _createClass(Fly, [{ + key: "request", + value: function request(url, data, options) { + var _this = this; + + var engine = new this.engine(); + var contentType = "Content-Type"; + var contentTypeLowerCase = contentType.toLowerCase(); + var interceptors = this.interceptors; + var requestInterceptor = interceptors.request; + var responseInterceptor = interceptors.response; + var requestInterceptorHandler = requestInterceptor.handler; + var promise = new Promise(function (resolve, reject) { + if (utils.isObject(url)) { + options = url; + url = options.url; + } + options = options || {}; + options.headers = options.headers || {}; + + function isPromise(p) { + // some polyfill implementation of Promise may be not standard, + // so, we test by duck-typing + return p && p.then && p.catch; + } + + /** + * If the request/response interceptor has been locked, + * the new request/response will enter a queue. otherwise, it will be performed directly. + * @param [promise] if the promise exist, means the interceptor is locked. + * @param [callback] + */ + function enqueueIfLocked(promise, callback) { + if (promise) { + promise.then(function () { + callback(); + }); + } else { + callback(); + } + } + + // make the http request + function makeRequest(options) { + data = options.body; + // Normalize the request url + url = utils.trim(options.url); + var baseUrl = utils.trim(options.baseURL || ""); + if (!url && isBrowser && !baseUrl) { url = location.href; } + if (url.indexOf("http") !== 0) { + var isAbsolute = url[0] === "/"; + if (!baseUrl && isBrowser) { + var arr = location.pathname.split("/"); + arr.pop(); + baseUrl = location.protocol + "//" + location.host + (isAbsolute ? "" : arr.join("/")); + } + if (baseUrl[baseUrl.length - 1] !== "/") { + baseUrl += "/"; + } + url = baseUrl + (isAbsolute ? url.substr(1) : url); + if (isBrowser) { + + // Normalize the url which contains the ".." or ".", such as + // "http://xx.com/aa/bb/../../xx" to "http://xx.com/xx" . + var t = document.createElement("a"); + t.href = url; + url = t.href; + } + } + + var responseType = utils.trim(options.responseType || ""); + var needQuery = ["GET", "HEAD", "DELETE", "OPTION"].indexOf(options.method) !== -1; + var dataType = utils.type(data); + var params = options.params || {}; + + // merge url params when the method is "GET" (data is object) + if (needQuery && dataType === "object") { + params = utils.merge(data, params); + } + // encode params to String + params = utils.formatParams(params); + + // save url params + var _params = []; + if (params) { + _params.push(params); + } + // Add data to url params when the method is "GET" (data is String) + if (needQuery && data && dataType === "string") { + _params.push(data); + } + + // make the final url + if (_params.length > 0) { + url += (url.indexOf("?") === -1 ? "?" : "&") + _params.join("&"); + } + + engine.open(options.method, url); + + // try catch for ie >=9 + try { + engine.withCredentials = !!options.withCredentials; + engine.timeout = options.timeout || 0; + if (responseType !== "stream") { + engine.responseType = responseType; + } + } catch (e) {} + + var customContentType = options.headers[contentType] || options.headers[contentTypeLowerCase]; + + // default content type + var _contentType = "application/x-www-form-urlencoded"; + // If the request data is json object, transforming it to json string, + // and set request content-type to "json". In browser, the data will + // be sent as RequestBody instead of FormData + if (utils.trim((customContentType || "").toLowerCase()) === _contentType) { + data = utils.formatParams(data); + } else if (!utils.isFormData(data) && ["object", "array"].indexOf(utils.type(data)) !== -1) { + _contentType = 'application/json;charset=utf-8'; + data = JSON.stringify(data); + } + //If user doesn't set content-type, set default. + if (!(customContentType || needQuery)) { + options.headers[contentType] = _contentType; + } + + for (var k in options.headers) { + if (k === contentType && utils.isFormData(data)) { + // Delete the content-type, Let the browser set it + delete options.headers[k]; + } else { + try { + // In browser environment, some header fields are readonly, + // write will cause the exception . + engine.setRequestHeader(k, options.headers[k]); + } catch (e) {} + } + } + + function onresult(handler, data, type) { + enqueueIfLocked(responseInterceptor.p, function () { + if (handler) { + //如果失败,添加请求信息 + if (type) { + data.request = options; + } + var ret = handler.call(responseInterceptor, data, Promise); + data = ret === undefined ? data : ret; + } + if (!isPromise(data)) { + data = Promise[type === 0 ? "resolve" : "reject"](data); + } + data.then(function (d) { + resolve(d); + }).catch(function (e) { + reject(e); + }); + }); + } + + function onerror(e) { + e.engine = engine; + onresult(responseInterceptor.onerror, e, -1); + } + + function Err(msg, status) { + this.message = msg; + this.status = status; + } + + engine.onload = function () { + try { + // The xhr of IE9 has not response field + var response = engine.response || engine.responseText; + if (response && options.parseJson && (engine.getResponseHeader(contentType) || "").indexOf("json") !== -1 + // Some third engine implementation may transform the response text to json object automatically, + // so we should test the type of response before transforming it + && !utils.isObject(response)) { + response = JSON.parse(response); + } + + var headers = engine.responseHeaders; + // In browser + if (!headers) { + headers = {}; + var items = (engine.getAllResponseHeaders() || "").split("\r\n"); + items.pop(); + items.forEach(function (e) { + if (!e) { return; } + var key = e.split(":")[0]; + headers[key] = engine.getResponseHeader(key); + }); + } + var status = engine.status; + var statusText = engine.statusText; + var _data = { data: response, headers: headers, status: status, statusText: statusText }; + // The _response filed of engine is set in adapter which be called in engine-wrapper.js + utils.merge(_data, engine._response); + if (status >= 200 && status < 300 || status === 304) { + _data.engine = engine; + _data.request = options; + onresult(responseInterceptor.handler, _data, 0); + } else { + var e = new Err(statusText, status); + e.response = _data; + onerror(e); + } + } catch (e) { + onerror(new Err(e.msg, engine.status)); + } + }; + + engine.onerror = function (e) { + onerror(new Err(e.msg || "Network Error", 0)); + }; + + engine.ontimeout = function () { + onerror(new Err("timeout [ " + engine.timeout + "ms ]", 1)); + }; + engine._options = options; + setTimeout(function () { + engine.send(needQuery ? null : data); + }, 0); + } + + enqueueIfLocked(requestInterceptor.p, function () { + utils.merge(options, JSON.parse(JSON.stringify(_this.config))); + var headers = options.headers; + headers[contentType] = headers[contentType] || headers[contentTypeLowerCase] || ""; + delete headers[contentTypeLowerCase]; + options.body = data || options.body; + url = utils.trim(url || ""); + options.method = options.method.toUpperCase(); + options.url = url; + var ret = options; + if (requestInterceptorHandler) { + ret = requestInterceptorHandler.call(requestInterceptor, options, Promise) || options; + } + if (!isPromise(ret)) { + ret = Promise.resolve(ret); + } + ret.then(function (d) { + //if options continue + if (d === options) { + makeRequest(d); + } else { + resolve(d); + } + }, function (err) { + reject(err); + }); + }); + }); + promise.engine = engine; + return promise; + } + }, { + key: "all", + value: function all(promises) { + return Promise.all(promises); + } + }, { + key: "spread", + value: function spread(callback) { + return function (arr) { + return callback.apply(null, arr); + }; + } + }]); + + return Fly; + }(); + + //For typeScript + + + Fly.default = Fly; + + ["get", "post", "put", "patch", "head", "delete"].forEach(function (e) { + Fly.prototype[e] = function (url, data, option) { + return this.request(url, data, utils.merge({ method: e }, option)); + }; + }); + ["lock", "unlock", "clear"].forEach(function (e) { + Fly.prototype[e] = function () { + this.interceptors.request[e](); + }; + }); + module.exports = Fly; + + /***/ }) + /******/ ]); + }); + }); + + var Fly$1 = unwrapExports(fly); + + // the core stuff to id if it's calling with jsonql + var DATA_KEY = 'data'; + var ERROR_KEY = 'error'; + + var JSONQL_PATH = 'jsonql'; + // according to the json query spec + var CONTENT_TYPE = 'application/vnd.api+json'; + var CHARSET = 'charset=utf-8'; + var DEFAULT_HEADER = { + 'Accept': CONTENT_TYPE, + 'Content-Type': [ CONTENT_TYPE, CHARSET ].join(';') + }; + + // export const INDEX = 'index'; use INDEX_KEY instead + var DEFAULT_TYPE = 'any'; + // new jsonp + var JSONP_CALLBACK_NAME = 'jsonqlJsonpCallback'; + + // methods allow + var API_REQUEST_METHODS = ['POST', 'PUT']; + // for contract-cli + var KEY_WORD = 'continue'; + + var TYPE_KEY = 'type'; + var OPTIONAL_KEY = 'optional'; + var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word + var ARGS_KEY = 'args'; + var CHECKER_KEY = 'checker'; + var ALIAS_KEY = 'alias'; + var LOGIN_NAME = 'login'; + var ISSUER_NAME = LOGIN_NAME; // legacy issue need to replace them later + var LOGOUT_NAME = 'logout'; + + var AUTH_HEADER = 'Authorization'; + var BEARER = 'Bearer'; + + // for client use @TODO need to clean this up some of them are not in use + var CREDENTIAL_STORAGE_KEY = 'credential'; + var CLIENT_STORAGE_KEY = 'storageKey'; + var CLIENT_AUTH_KEY = 'authKey'; + // contract key + var CONTRACT_KEY_NAME = 'X-JSONQL-CV-KEY'; + var SHOW_CONTRACT_DESC_PARAM = {desc: 'y'}; + + var OR_SEPERATOR = '|'; + + var STRING_TYPE = 'string'; + var BOOLEAN_TYPE = 'boolean'; + var ARRAY_TYPE = 'array'; + var OBJECT_TYPE = 'object'; + + var NUMBER_TYPE = 'number'; + var ARRAY_TYPE_LFT = 'array.<'; + var ARRAY_TYPE_RGT = '>'; + + var NO_ERROR_MSG = 'No message'; + var NO_STATUS_CODE = -1; + var HSA_ALGO = 'HS256'; + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Built-in value references. */ + var Symbol$1 = root.Symbol; + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Built-in value references. */ + var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsZWJ = '\\u200d'; + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f', + reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', + rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', + rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, + rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange$1 + ']', + rsCombo = '[' + rsComboRange$1 + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange$1 + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange$1 + ']?', + rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** `Object#toString` result references. */ + var boolTag = '[object Boolean]'; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** `Object#toString` result references. */ + var numberTag = '[object Number]'; + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN$1(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** `Object#toString` result references. */ + var stringTag = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** Built-in value references. */ + var getPrototype = overArg(Object.getPrototypeOf, Object); + + /** `Object#toString` result references. */ + var objectTag = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto$2 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]'; + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$3.hasOwnProperty; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + } + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + arrayTag = '[object Array]', + boolTag$1 = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag$1 = '[object Number]', + objectTag$1 = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag$1 = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag$1] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag$1] = + typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag$1] = + typedArrayTags[weakMapTag] = false; + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** Detect free variable `exports`. */ + var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports$1 && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$4.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$3.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; + + return value === proto; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); + + /** Used for built-in method references. */ + var objectProto$6 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$6.hasOwnProperty; + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$4.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag$1 = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString$1.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto$2 = Function.prototype, + objectProto$7 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$2 = funcProto$2.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$5 = objectProto$7.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /* Built-in method references that are verified to be native. */ + var Map$1 = getNative(root, 'Map'); + + /* Built-in method references that are verified to be native. */ + var nativeCreate = getNative(Object, 'create'); + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$8 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$6 = objectProto$8.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$6.call(data, key) ? data[key] : undefined; + } + + /** Used for built-in method references. */ + var objectProto$9 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$7 = objectProto$9.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key); + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; + } + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map$1 || ListCache), + 'string': new Hash + }; + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED$2); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** Built-in value references. */ + var Uint8Array$1 = root.Uint8Array; + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$1 = 1, + COMPARE_UNORDERED_FLAG$1 = 2; + + /** `Object#toString` result references. */ + var boolTag$2 = '[object Boolean]', + dateTag$1 = '[object Date]', + errorTag$1 = '[object Error]', + mapTag$1 = '[object Map]', + numberTag$2 = '[object Number]', + regexpTag$1 = '[object RegExp]', + setTag$1 = '[object Set]', + stringTag$2 = '[object String]', + symbolTag$1 = '[object Symbol]'; + + var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$1 = '[object DataView]'; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$1 = Symbol$1 ? Symbol$1.prototype : undefined, + symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag$1: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag$1: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { + return false; + } + return true; + + case boolTag$2: + case dateTag$1: + case numberTag$2: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag$1: + return object.name == other.name && object.message == other.message; + + case regexpTag$1: + case stringTag$2: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag$1: + var convert = mapToArray; + + case setTag$1: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG$1; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag$1: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** Used for built-in method references. */ + var objectProto$a = Object.prototype; + + /** Built-in value references. */ + var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable$1.call(object, symbol); + }); + }; + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$2 = 1; + + /** Used for built-in method references. */ + var objectProto$b = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$8 = objectProto$b.hasOwnProperty; + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'); + + /* Built-in method references that are verified to be native. */ + var Promise$1 = getNative(root, 'Promise'); + + /* Built-in method references that are verified to be native. */ + var Set$1 = getNative(root, 'Set'); + + /* Built-in method references that are verified to be native. */ + var WeakMap$1 = getNative(root, 'WeakMap'); + + /** `Object#toString` result references. */ + var mapTag$2 = '[object Map]', + objectTag$2 = '[object Object]', + promiseTag = '[object Promise]', + setTag$2 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; + + var dataViewTag$2 = '[object DataView]'; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map$1), + promiseCtorString = toSource(Promise$1), + setCtorString = toSource(Set$1), + weakMapCtorString = toSource(WeakMap$1); + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$2) || + (Map$1 && getTag(new Map$1) != mapTag$2) || + (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || + (Set$1 && getTag(new Set$1) != setTag$2) || + (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag$1)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag$2 ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag$2; + case mapCtorString: return mapTag$2; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag$2; + case weakMapCtorString: return weakMapTag$1; + } + } + return result; + }; + } + + var getTag$1 = getTag; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$3 = 1; + + /** `Object#toString` result references. */ + var argsTag$2 = '[object Arguments]', + arrayTag$1 = '[object Array]', + objectTag$3 = '[object Object]'; + + /** Used for built-in method references. */ + var objectProto$c = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$9 = objectProto$c.hasOwnProperty; + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag$1 : getTag$1(object), + othTag = othIsArr ? arrayTag$1 : getTag$1(other); + + objTag = objTag == argsTag$2 ? objectTag$3 : objTag; + othTag = othTag == argsTag$2 ? objectTag$3 : othTag; + + var objIsObj = objTag == objectTag$3, + othIsObj = othTag == objectTag$3, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { + var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$4 = 1, + COMPARE_UNORDERED_FLAG$2 = 2; + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** Used to match property names within property paths. */ + var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** Used as references for various `Number` constants. */ + var INFINITY$1 = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$5 = 1, + COMPARE_UNORDERED_FLAG$3 = 2; + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); + }; + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ + function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** Detect free variable `exports`. */ + var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; + + /** Built-in value references. */ + var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, + allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** Built-in value references. */ + var objectCreate = Object.create; + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** Used for built-in method references. */ + var objectProto$d = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$a = objectProto$d.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty$a.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$e = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$b = objectProto$e.hasOwnProperty; + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$b.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max; + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeNow = Date.now; + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** Error message constants. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols$1 = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(baseIteratee(predicate))); + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate), baseForOwn); + } + + /** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ + + function notEmpty (a) { + if (isArray(a)) { + return true; + } + return a !== undefined && a !== null && trim(a) !== ''; + } + + // validator numbers + /** + * @2015-05-04 found a problem if the value is a number like string + * it will pass, so add a check if it's string before we pass to next + * @param {number} value expected value + * @return {boolean} true if OK + */ + var checkIsNumber = function(value) { + return isString(value) ? false : !isNaN$1( parseFloat(value) ) + }; + + // validate string type + /** + * @param {string} value expected value + * @return {boolean} true if OK + */ + var checkIsString = function(value) { + return (trim(value) !== '') ? isString(value) : false; + }; + + // check for boolean + /** + * @param {boolean} value expected + * @return {boolean} true if OK + */ + var checkIsBoolean = function(value) { + return isBoolean(value); + }; + + // validate any thing only check if there is something + /** + * @param {*} value the value + * @param {boolean} [checkNull=true] strict check if there is null value + * @return {boolean} true is OK + */ + var checkIsAny = function(value, checkNull) { + if ( checkNull === void 0 ) checkNull = true; + + if (!isUndefined(value) && value !== '' && trim(value) !== '') { + if (checkNull === false || (checkNull === true && !isNull(value))) { + return true; + } + } + return false; + }; + + // Good practice rule - No magic number + + var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; + var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; + var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; + // @TODO the jsdoc return array. and we should also allow array syntax + var DEFAULT_TYPE$1 = DEFAULT_TYPE; + var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; + var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; + + var TYPE_KEY$1 = TYPE_KEY; + var OPTIONAL_KEY$1 = OPTIONAL_KEY; + var ENUM_KEY$1 = ENUM_KEY; + var ARGS_KEY$1 = ARGS_KEY; + var CHECKER_KEY$1 = CHECKER_KEY; + var ALIAS_KEY$1 = ALIAS_KEY; + + var ARRAY_TYPE$1 = ARRAY_TYPE; + var OBJECT_TYPE$1 = OBJECT_TYPE; + var STRING_TYPE$1 = STRING_TYPE; + var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; + var NUMBER_TYPE$1 = NUMBER_TYPE; + var KEY_WORD$1 = KEY_WORD; + var OR_SEPERATOR$1 = OR_SEPERATOR; + + // not actually in use + // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; + + // primitive types + + /** + * this is a wrapper method to call different one based on their type + * @param {string} type to check + * @return {function} a function to handle the type + */ + var combineFn = function(type) { + switch (type) { + case NUMBER_TYPE$1: + return checkIsNumber; + case STRING_TYPE$1: + return checkIsString; + case BOOLEAN_TYPE$1: + return checkIsBoolean; + default: + return checkIsAny; + } + }; + + // validate array type + + /** + * @param {array} value expected + * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well + * @return {boolean} true if OK + */ + var checkIsArray = function(value, type) { + if ( type === void 0 ) type=''; + + if (isArray(value)) { + if (type === '' || trim(type)==='') { + return true; + } + // we test it in reverse + // @TODO if the type is an array (OR) then what? + // we need to take into account this could be an array + var c = value.filter(function (v) { return !combineFn(type)(v); }); + return !(c.length > 0) + } + return false; + }; + + /** + * check if it matches the array. pattern + * @param {string} type + * @return {boolean|array} false means NO, always return array + */ + var isArrayLike$1 = function(type) { + // @TODO could that have something like array<> instead of array.<>? missing the dot? + // because type script is Array without the dot + if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { + var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); + if (_type.indexOf(OR_SEPERATOR$1)) { + return _type.split(OR_SEPERATOR$1) + } + return [_type] + } + return false; + }; + + /** + * we might encounter something like array. then we need to take it apart + * @param {object} p the prepared object for processing + * @param {string|array} type the type came from + * @return {boolean} for the filter to operate on + */ + var arrayTypeHandler = function(p, type) { + var arg = p.arg; + // need a special case to handle the OR type + // we need to test the args instead of the type(s) + if (type.length > 1) { + return !arg.filter(function (v) { return ( + !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) + ); }).length; + } + // type is array so this will be or! + return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; + }; + + // validate object type + /** + * @TODO if provide with the keys then we need to check if the key:value type as well + * @param {object} value expected + * @param {array} [keys=null] if it has the keys array to compare as well + * @return {boolean} true if OK + */ + var checkIsObject = function(value, keys) { + if ( keys === void 0 ) keys=null; + + if (isPlainObject(value)) { + if (!keys) { + return true; + } + if (checkIsArray(keys)) { + // please note we DON'T care if some is optional + // plese refer to the contract.json for the keys + return !keys.filter(function (key) { + var _value = value[key.name]; + return !(key.type.length > key.type.filter(function (type) { + var tmp; + if (!isUndefined(_value)) { + if ((tmp = isArrayLike$1(type)) !== false) { + return !arrayTypeHandler({arg: _value}, tmp) + // return tmp.filter(t => !checkIsArray(_value, t)).length; + // @TODO there might be an object within an object with keys as well :S + } + return !combineFn(type)(_value) + } + return true; + }).length) + }).length; + } + } + return false; + }; + + /** + * fold this into it's own function to handler different object type + * @param {object} p the prepared object for process + * @return {boolean} + */ + var objectTypeHandler = function(p) { + var arg = p.arg; + var param = p.param; + var _args = [arg]; + if (Array.isArray(param.keys) && param.keys.length) { + _args.push(param.keys); + } + // just simple check + return checkIsObject.apply(null, _args) + }; + + /** + * This is a custom error to throw when server throw a 406 + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var Jsonql406Error = /*@__PURE__*/(function (Error) { + function Jsonql406Error() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + // We can't access the static name from an instance + // but we can do it like this + this.className = Jsonql406Error.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Jsonql406Error); + } + } + + if ( Error ) Jsonql406Error.__proto__ = Error; + Jsonql406Error.prototype = Object.create( Error && Error.prototype ); + Jsonql406Error.prototype.constructor = Jsonql406Error; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 406; + }; + + staticAccessors.name.get = function () { + return 'Jsonql406Error'; + }; + + Object.defineProperties( Jsonql406Error, staticAccessors ); + + return Jsonql406Error; + }(Error)); + + /** + * This is a custom error to throw when server throw a 500 + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var Jsonql500Error = /*@__PURE__*/(function (Error) { + function Jsonql500Error() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = Jsonql500Error.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Jsonql500Error); + } + } + + if ( Error ) Jsonql500Error.__proto__ = Error; + Jsonql500Error.prototype = Object.create( Error && Error.prototype ); + Jsonql500Error.prototype.constructor = Jsonql500Error; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 500; + }; + + staticAccessors.name.get = function () { + return 'Jsonql500Error'; + }; + + Object.defineProperties( Jsonql500Error, staticAccessors ); + + return Jsonql500Error; + }(Error)); + + /** + * This is a custom error to throw when pass credential but fail + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlAuthorisationError = /*@__PURE__*/(function (Error) { + function JsonqlAuthorisationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlAuthorisationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlAuthorisationError); + } + } + + if ( Error ) JsonqlAuthorisationError.__proto__ = Error; + JsonqlAuthorisationError.prototype = Object.create( Error && Error.prototype ); + JsonqlAuthorisationError.prototype.constructor = JsonqlAuthorisationError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 401; + }; + + staticAccessors.name.get = function () { + return 'JsonqlAuthorisationError'; + }; + + Object.defineProperties( JsonqlAuthorisationError, staticAccessors ); + + return JsonqlAuthorisationError; + }(Error)); + + /** + * This is a custom error when not supply the credential and try to get contract + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlContractAuthError = /*@__PURE__*/(function (Error) { + function JsonqlContractAuthError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlContractAuthError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlContractAuthError); + } + } + + if ( Error ) JsonqlContractAuthError.__proto__ = Error; + JsonqlContractAuthError.prototype = Object.create( Error && Error.prototype ); + JsonqlContractAuthError.prototype.constructor = JsonqlContractAuthError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 401; + }; + + staticAccessors.name.get = function () { + return 'JsonqlContractAuthError'; + }; + + Object.defineProperties( JsonqlContractAuthError, staticAccessors ); + + return JsonqlContractAuthError; + }(Error)); + + /** + * This is a custom error to throw when the resolver throw error and capture inside the middleware + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlResolverAppError = /*@__PURE__*/(function (Error) { + function JsonqlResolverAppError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlResolverAppError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlResolverAppError); + } + } + + if ( Error ) JsonqlResolverAppError.__proto__ = Error; + JsonqlResolverAppError.prototype = Object.create( Error && Error.prototype ); + JsonqlResolverAppError.prototype.constructor = JsonqlResolverAppError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 500; + }; + + staticAccessors.name.get = function () { + return 'JsonqlResolverAppError'; + }; + + Object.defineProperties( JsonqlResolverAppError, staticAccessors ); + + return JsonqlResolverAppError; + }(Error)); + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode = function () { + try { + if (!isBrowser() && global$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI() { + if (isBrowser()) { + return 'browser' + } + if (isNode()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + } + + if ( Error ) JsonqlBaseError.__proto__ = Error; + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI() + }; + + return JsonqlBaseError; + }(Error)); + + /** + * This is a custom error to throw when could not find the resolver + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlResolverNotFoundError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlResolverNotFoundError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlResolverNotFoundError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlResolverNotFoundError); + } + } + + if ( JsonqlBaseError ) JsonqlResolverNotFoundError.__proto__ = JsonqlBaseError; + JsonqlResolverNotFoundError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlResolverNotFoundError.prototype.constructor = JsonqlResolverNotFoundError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 404; + }; + + staticAccessors.name.get = function () { + return 'JsonqlResolverNotFoundError'; + }; + + Object.defineProperties( JsonqlResolverNotFoundError, staticAccessors ); + + return JsonqlResolverNotFoundError; + }(JsonqlBaseError)); + + // this get throw from within the checkOptions when run through the enum failed + var JsonqlEnumError = /*@__PURE__*/(function (Error) { + function JsonqlEnumError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlEnumError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlEnumError); + } + } + + if ( Error ) JsonqlEnumError.__proto__ = Error; + JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); + JsonqlEnumError.prototype.constructor = JsonqlEnumError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlEnumError'; + }; + + Object.defineProperties( JsonqlEnumError, staticAccessors ); + + return JsonqlEnumError; + }(Error)); + + // this will throw from inside the checkOptions + var JsonqlTypeError = /*@__PURE__*/(function (Error) { + function JsonqlTypeError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlTypeError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlTypeError); + } + } + + if ( Error ) JsonqlTypeError.__proto__ = Error; + JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); + JsonqlTypeError.prototype.constructor = JsonqlTypeError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlTypeError'; + }; + + Object.defineProperties( JsonqlTypeError, staticAccessors ); + + return JsonqlTypeError; + }(Error)); + + // allow supply a custom checker function + // if that failed then we throw this error + var JsonqlCheckerError = /*@__PURE__*/(function (Error) { + function JsonqlCheckerError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlCheckerError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlCheckerError); + } + } + + if ( Error ) JsonqlCheckerError.__proto__ = Error; + JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); + JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlCheckerError'; + }; + + Object.defineProperties( JsonqlCheckerError, staticAccessors ); + + return JsonqlCheckerError; + }(Error)); + + // custom validation error class + // when validaton failed + var JsonqlValidationError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) JsonqlValidationError.__proto__ = JsonqlBaseError; + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; + }(JsonqlBaseError)); + + /** + * This is a custom error to throw whenever a error happen inside the jsonql + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlError); + // this.detail = this.stack; + } + } + + if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; + JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlError.prototype.constructor = JsonqlError; + + var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlError'; + }; + + staticAccessors.statusCode.get = function () { + return NO_STATUS_CODE; + }; + + Object.defineProperties( JsonqlError, staticAccessors ); + + return JsonqlError; + }(JsonqlBaseError)); + + // this is from an example from Koa team to use for internal middleware ctx.throw + // but after the test the res.body part is unable to extract the required data + // I keep this one here for future reference + + var JsonqlServerError = /*@__PURE__*/(function (Error) { + function JsonqlServerError(statusCode, message) { + Error.call(this, message); + this.statusCode = statusCode; + this.className = JsonqlServerError.name; + } + + if ( Error ) JsonqlServerError.__proto__ = Error; + JsonqlServerError.prototype = Object.create( Error && Error.prototype ); + JsonqlServerError.prototype.constructor = JsonqlServerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlServerError'; + }; + + Object.defineProperties( JsonqlServerError, staticAccessors ); + + return JsonqlServerError; + }(Error)); + + // server side + + var errors = /*#__PURE__*/Object.freeze({ + Jsonql406Error: Jsonql406Error, + Jsonql500Error: Jsonql500Error, + JsonqlAuthorisationError: JsonqlAuthorisationError, + JsonqlContractAuthError: JsonqlContractAuthError, + JsonqlResolverAppError: JsonqlResolverAppError, + JsonqlResolverNotFoundError: JsonqlResolverNotFoundError, + JsonqlEnumError: JsonqlEnumError, + JsonqlTypeError: JsonqlTypeError, + JsonqlCheckerError: JsonqlCheckerError, + JsonqlValidationError: JsonqlValidationError, + JsonqlError: JsonqlError, + JsonqlServerError: JsonqlServerError + }); + + // this will add directly to the then call in each http call + var JsonqlError$1 = JsonqlError; + + /** + * We can not just check something like result.data what if the result if false? + * @param {object} obj the result object + * @param {string} key we want to check if its exist or not + * @return {boolean} true on found + */ + var isKeyInObject = function (obj, key) { + var keys = Object.keys(obj); + return !!keys.filter(function (k) { return key === k; }).length; + }; + + /** + * It will ONLY have our own jsonql specific implement check + * @param {object} result the server return result + * @return {object} this will just throw error + */ + function clientErrorsHandler(result) { + if (isKeyInObject(result, 'error')) { + var error = result.error; + var className = error.className; + var name = error.name; + var errorName = className || name; + // just throw the whole thing back + var msg = error.message || NO_ERROR_MSG; + var detail = error.detail || error; + if (errorName && errors[errorName]) { + throw new errors[className](msg, detail) + } + throw new JsonqlError$1(msg, detail) + } + // pass through to the next + return result; + } + + /** + * this will put into generator call at the very end and catch + * the error throw from inside then throw again + * this is necessary because we split calls inside and the throw + * will not reach the actual client unless we do it this way + * @param {object} e Error + * @return {void} just throw + */ + function finalCatch(e) { + // this is a hack to get around the validateAsync not actually throw error + // instead it just rejected it with the array of failed parameters + if (Array.isArray(e)) { + // if we want the message then I will have to create yet another function + // to wrap this function to provide the name prop + throw new JsonqlValidationError('', e) + } + var msg = e.message || NO_ERROR_MSG; + var detail = e.detail || e; + switch (true) { + case e instanceof Jsonql406Error: + throw new Jsonql406Error(msg, detail) + case e instanceof Jsonql500Error: + throw new Jsonql500Error(msg, detail) + case e instanceof JsonqlAuthorisationError: + throw new JsonqlAuthorisationError(msg, detail) + case e instanceof JsonqlContractAuthError: + throw new JsonqlContractAuthError(msg, detail) + case e instanceof JsonqlResolverAppError: + throw new JsonqlResolverAppError(msg, detail) + case e instanceof JsonqlResolverNotFoundError: + throw new JsonqlResolverNotFoundError(msg, detail) + case e instanceof JsonqlEnumError: + throw new JsonqlEnumError(msg, detail) + case e instanceof JsonqlTypeError: + throw new JsonqlTypeError(msg, detail) + case e instanceof JsonqlCheckerError: + throw new JsonqlCheckerError(msg, detail) + case e instanceof JsonqlValidationError: + throw new JsonqlValidationError(msg, detail) + case e instanceof JsonqlServerError: + throw new JsonqlServerError(msg, detail) + default: + throw new JsonqlError(msg, detail) + } + } + + /** + * just a simple util for helping to debug + * @param {array} args arguments + * @return {void} + */ + function log() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.console) { + Reflect.apply(console.log, console, args); + } + } catch(e) {} + } + + // move the index.js code here that make more sense to find where things are + // import debug from 'debug' + // const debugFn = debug('jsonql-params-validator:validator') + // also export this for use in other places + + /** + * We need to handle those optional parameter without a default value + * @param {object} params from contract.json + * @return {boolean} for filter operation false is actually OK + */ + var optionalHandler = function( params ) { + var arg = params.arg; + var param = params.param; + if (notEmpty(arg)) { + // debug('call optional handler', arg, params); + // loop through the type in param + return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } + ).length) + } + return false; + }; + + /** + * actually picking the validator + * @param {*} type for checking + * @param {*} value for checking + * @return {boolean} true on OK + */ + var validateHandler = function(type, value) { + var tmp; + switch (true) { + case type === OBJECT_TYPE$1: + // debugFn('call OBJECT_TYPE') + return !objectTypeHandler(value) + case type === ARRAY_TYPE$1: + // debugFn('call ARRAY_TYPE') + return !checkIsArray(value.arg) + // @TODO when the type is not present, it always fall through here + // so we need to find a way to actually pre-check the type first + // AKA check the contract.json map before running here + case (tmp = isArrayLike$1(type)) !== false: + // debugFn('call ARRAY_LIKE: %O', value) + return !arrayTypeHandler(value, tmp) + default: + return !combineFn(type)(value.arg) + } + }; + + /** + * it get too longer to fit in one line so break it out from the fn below + * @param {*} arg value + * @param {object} param config + * @return {*} value or apply default value + */ + var getOptionalValue = function(arg, param) { + if (!isUndefined(arg)) { + return arg; + } + return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) + }; + + /** + * padding the arguments with defaultValue if the arguments did not provide the value + * this will be the name export + * @param {array} args normalized arguments + * @param {array} params from contract.json + * @return {array} merge the two together + */ + var normalizeArgs = function(args, params) { + // first we should check if this call require a validation at all + // there will be situation where the function doesn't need args and params + if (!checkIsArray(params)) { + // debugFn('params value', params) + throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) + } + if (params.length === 0) { + return []; + } + if (!checkIsArray(args)) { + throw new JsonqlError(ARGS_NOT_ARRAY_ERR) + } + // debugFn(args, params); + // fall through switch + switch(true) { + case args.length == params.length: // standard + log(1); + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, + param: params[i] + } + ); }) + case params[0].variable === true: // using spread syntax + log(2); + var type = params[0].type; + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, // keep the index for reference + param: params[i] || { type: type, name: '_' } + } + ); }) + // with optional defaultValue parameters + case args.length < params.length: + log(3); + return params.map(function (param, i) { return ( + { + param: param, + index: i, + arg: getOptionalValue(args[i], param), + optional: param.optional || false + } + ); }) + // this one pass more than it should have anything after the args.length will be cast as any type + case args.length > params.length: + log(4); + var ctn = params.length; + // this happens when we have those array. type + var _type = [ DEFAULT_TYPE$1 ]; + // we only looking at the first one, this might be a @BUG + /* + if ((tmp = isArrayLike(params[0].type[0])) !== false) { + _type = tmp; + } */ + // if we use the params as guide then the rest will get throw out + // which is not what we want, instead, anything without the param + // will get a any type and optional flag + return args.map(function (arg, i) { + var optional = i >= ctn ? true : !!params[i].optional; + var param = params[i] || { type: _type, name: ("_" + i) }; + return { + arg: optional ? getOptionalValue(arg, param) : arg, + index: i, + param: param, + optional: optional + } + }) + // @TODO find out if there is more cases not cover + default: // this should never happen + log(5); + // debugFn('args', args) + // debugFn('params', params) + // this is unknown therefore we just throw it! + throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) + } + }; + + // what we want is after the validaton we also get the normalized result + // which is with the optional property if the argument didn't provide it + /** + * process the array of params back to their arguments + * @param {array} result the params result + * @return {array} arguments + */ + var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; + + /** + * validator main interface + * @param {array} args the arguments pass to the method call + * @param {array} params from the contract for that method + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {array} empty array on success, or failed parameter and reasons + */ + var validateSync = function(args, params, withResult) { + var obj; + + if ( withResult === void 0 ) withResult = false; + var cleanArgs = normalizeArgs(args, params); + var checkResult = cleanArgs.filter(function (p) { + // v1.4.4 this fixed the problem, the root level optional is from the last fn + if (p.optional === true || p.param.optional === true) { + return optionalHandler(p) + } + // because array of types means OR so if one pass means pass + return !(p.param.type.length > p.param.type.filter( + function (type) { return validateHandler(type, p); } + ).length) + }); + // using the same convention we been using all this time + return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) + }; + + /** + * A wrapper method that return promise + * @param {array} args arguments + * @param {array} params from contract.json + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {object} promise.then or catch + */ + var validateAsync = function(args, params, withResult) { + if ( withResult === void 0 ) withResult = false; + + return new Promise(function (resolver, rejecter) { + var result = validateSync(args, params, withResult); + if (withResult) { + return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY]) + : resolver(result[DATA_KEY]) + } + // the different is just in the then or catch phrase + return result.length ? rejecter(result) : resolver([]) + }) + }; + + /** + * @param {array} arr Array for check + * @param {*} value target + * @return {boolean} true on successs + */ + var isInArray = function(arr, value) { + return !!arr.filter(function (a) { return a === value; }).length; + }; + + var isKeyInObject$1 = function(obj, key) { + var keys = Object.keys(obj); + return isInArray(keys, key) + }; + + // just not to make my head hurt + var isEmpty = function (value) { return !notEmpty(value); }; + + /** + * Map the alias to their key then grab their value over + * @param {object} config the user supplied config + * @param {object} appProps the default option map + * @return {object} the config keys replaced with the appProps key by the ALIAS + */ + function mapAliasConfigKeys(config, appProps) { + // need to do two steps + // 1. take key with alias key + var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); + if (isEqual(aliasMap, {})) { + return config; + } + return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) + } + + /** + * We only want to run the valdiation against the config (user supplied) value + * but keep the defaultOptions untouch + * @param {object} config configuraton supplied by user + * @param {object} appProps the default options map + * @return {object} the pristine values that will add back to the final output + */ + function preservePristineValues(config, appProps) { + // @BUG this will filter out those that is alias key + // we need to first map the alias keys back to their full key + var _config = mapAliasConfigKeys(config, appProps); + // take the default value out + var pristineValues = mapValues( + omitBy(appProps, function (value, key) { return isKeyInObject$1(_config, key); }), + function (value) { return value.args; } + ); + // for testing the value + var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !isKeyInObject$1(_config, key); }); + // output + return { + pristineValues: pristineValues, + checkAgainstAppProps: checkAgainstAppProps, + config: _config // passing this correct values back + } + } + + /** + * This will take the value that is ONLY need to check + * @param {object} config that one + * @param {object} props map for creating checking + * @return {object} put that arg into the args + */ + function processConfigAction(config, props) { + // debugFn('processConfigAction', props) + // v.1.2.0 add checking if its mark optional and the value is empty then pass + return mapValues(props, function (value, key) { + var obj, obj$1; + + return ( + isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) + ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) + : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) + ); + } + ) + } + + /** + * Quick transform + * @TODO we should only validate those that is pass from the config + * and pass through those values that is from the defaultOptions + * @param {object} opts that one + * @param {object} appProps mutation configuration options + * @return {object} put that arg into the args + */ + function prepareArgsForValidation(opts, appProps) { + var ref = preservePristineValues(opts, appProps); + var config = ref.config; + var pristineValues = ref.pristineValues; + var checkAgainstAppProps = ref.checkAgainstAppProps; + // output + return [ + processConfigAction(config, checkAgainstAppProps), + pristineValues + ] + } + + // breaking the whole thing up to see what cause the multiple calls issue + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:validation') + + /** + * just make sure it returns an array to use + * @param {*} arg input + * @return {array} output + */ + var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; + + /** + * DIY in array + * @param {array} arr to check against + * @param {*} value to check + * @return {boolean} true on OK + */ + var inArray = function (arr, value) { return ( + !!arr.filter(function (v) { return v === value; }).length + ); }; + + /** + * break out to make the code easier to read + * @param {object} value to process + * @param {function} cb the validateSync + * @return {array} empty on success + */ + function validateHandler$1(value, cb) { + var obj; + + // cb is the validateSync methods + var args = [ + [ value[ARGS_KEY$1] ], + [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] + ]; + // debugFn('validateHandler', args) + return Reflect.apply(cb, null, args) + } + + /** + * Check against the enum value if it's provided + * @param {*} value to check + * @param {*} enumv to check against if it's not false + * @return {boolean} true on OK + */ + var enumHandler = function (value, enumv) { + if (checkIsArray(enumv)) { + return inArray(enumv, value) + } + return true; + }; + + /** + * Allow passing a function to check the value + * There might be a problem here if the function is incorrect + * and that will makes it hard to debug what is going on inside + * @TODO there could be a few feature add to this one under different circumstance + * @param {*} value to check + * @param {function} checker for checking + */ + var checkerHandler = function (value, checker) { + try { + return isFunction(checker) ? checker.apply(null, [value]) : false; + } catch (e) { + return false; + } + }; + + /** + * Taken out from the runValidaton this only validate the required values + * @param {array} args from the config2argsAction + * @param {function} cb validateSync + * @return {array} of configuration values + */ + function runValidationAction(cb) { + return function (value, key) { + // debugFn('runValidationAction', key, value) + if (value[KEY_WORD$1]) { + return value[ARGS_KEY$1] + } + var check = validateHandler$1(value, cb); + if (check.length) { + log('runValidationAction', key, value); + throw new JsonqlTypeError(key, check) + } + if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { + log(ENUM_KEY$1, value[ENUM_KEY$1]); + throw new JsonqlEnumError(key) + } + if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { + log(CHECKER_KEY$1, value[CHECKER_KEY$1]); + throw new JsonqlCheckerError(key) + } + return value[ARGS_KEY$1] + } + } + + /** + * @param {object} args from the config2argsAction + * @param {function} cb validateSync + * @return {object} of configuration values + */ + function runValidation(args, cb) { + var argsForValidate = args[0]; + var pristineValues = args[1]; + // turn the thing into an array and see what happen here + // debugFn('_args', argsForValidate) + var result = mapValues(argsForValidate, runValidationAction(cb)); + return merge(result, pristineValues) + } + + /// this is port back from the client to share across all projects + + // import debug from 'debug' + // const debugFn = debug('jsonql-params-validator:check-options-async') + + /** + * Quick transform + * @param {object} config that one + * @param {object} appProps mutation configuration options + * @return {object} put that arg into the args + */ + var configToArgs = function (config, appProps) { + return Promise.resolve( + prepareArgsForValidation(config, appProps) + ) + }; + + /** + * @param {object} config user provide configuration option + * @param {object} appProps mutation configuration options + * @param {object} constProps the immutable configuration options + * @param {function} cb the validateSync method + * @return {object} Promise resolve merge config object + */ + function checkOptionsAsync(config, appProps, constProps, cb) { + if ( config === void 0 ) config = {}; + + return configToArgs(config, appProps) + .then(function (args1) { + // debugFn('args', args1) + return runValidation(args1, cb) + }) + // next if every thing good then pass to final merging + .then(function (args2) { return merge({}, args2, constProps); }) + } + + // this is port back from the client to share across all projects + + /** + * @param {object} config user provide configuration option + * @param {object} appProps mutation configuration options + * @param {object} constProps the immutable configuration options + * @param {function} cb the validateSync method + * @return {object} Promise resolve merge config object + */ + function checkOptionsSync(config, appProps, constProps, cb) { + if ( config === void 0 ) config = {}; + + return merge( + runValidation( + prepareArgsForValidation(config, appProps), + cb + ), + constProps + ) + } + + // create function to construct the config entry so we don't need to keep building object + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:construct-config'); + /** + * @param {*} args value + * @param {string} type for value + * @param {boolean} [optional=false] + * @param {boolean|array} [enumv=false] + * @param {boolean|function} [checker=false] + * @return {object} config entry + */ + function constructConfigFn(args, type, optional, enumv, checker, alias) { + if ( optional === void 0 ) optional=false; + if ( enumv === void 0 ) enumv=false; + if ( checker === void 0 ) checker=false; + if ( alias === void 0 ) alias=false; + + var base = {}; + base[ARGS_KEY] = args; + base[TYPE_KEY] = type; + if (optional === true) { + base[OPTIONAL_KEY] = true; + } + if (checkIsArray(enumv)) { + base[ENUM_KEY] = enumv; + } + if (isFunction(checker)) { + base[CHECKER_KEY] = checker; + } + if (isString(alias)) { + base[ALIAS_KEY] = alias; + } + return base; + } + + // export also create wrapper methods + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:index'); + + /** + * This has a different interface + * @param {*} value to supply + * @param {string|array} type for checking + * @param {object} params to map against the config check + * @param {array} params.enumv NOT enum + * @param {boolean} params.optional false then nothing + * @param {function} params.checker need more work on this one later + * @param {string} params.alias mostly for cmd + */ + var createConfig = function (value, type, params) { + if ( params === void 0 ) params = {}; + + // Note the enumv not ENUM + // const { enumv, optional, checker, alias } = params; + // let args = [value, type, optional, enumv, checker, alias]; + var o = params[OPTIONAL_KEY]; + var e = params[ENUM_KEY]; + var c = params[CHECKER_KEY]; + var a = params[ALIAS_KEY]; + return constructConfigFn.apply(null, [value, type, o, e, c, a]) + }; + + /** + * We recreate the method here to avoid the circlar import + * @param {object} config user supply configuration + * @param {object} appProps mutation options + * @param {object} [constantProps={}] optional: immutation options + * @return {object} all checked configuration + */ + var checkConfigAsync = function(validateSync) { + return function(config, appProps, constantProps) { + if ( constantProps === void 0 ) constantProps= {}; + + return checkOptionsAsync(config, appProps, constantProps, validateSync) + } + }; + + // copy of above but it's sync + var checkConfig = function(validateSync) { + return function(config, appProps, constantProps) { + if ( constantProps === void 0 ) constantProps = {}; + + return checkOptionsSync(config, appProps, constantProps, validateSync) + } + }; + + // export + var isString$1 = checkIsString; + var isArray$1 = checkIsArray; + var validateAsync$1 = validateAsync; + + var createConfig$1 = createConfig; + + var checkConfigAsync$1 = checkConfigAsync(validateSync); + var checkConfig$1 = checkConfig(validateSync); + + var assign = make_assign(); + var create = make_create(); + var trim$1 = make_trim(); + var Global = (typeof window !== 'undefined' ? window : commonjsGlobal); + + var util = { + assign: assign, + create: create, + trim: trim$1, + bind: bind, + slice: slice, + each: each, + map: map, + pluck: pluck, + isList: isList, + isFunction: isFunction$1, + isObject: isObject$1, + Global: Global + }; + + function make_assign() { + if (Object.assign) { + return Object.assign + } else { + return function shimAssign(obj, props1, props2, etc) { + var arguments$1 = arguments; + + for (var i = 1; i < arguments.length; i++) { + each(Object(arguments$1[i]), function(val, key) { + obj[key] = val; + }); + } + return obj + } + } + } + + function make_create() { + if (Object.create) { + return function create(obj, assignProps1, assignProps2, etc) { + var assignArgsList = slice(arguments, 1); + return assign.apply(this, [Object.create(obj)].concat(assignArgsList)) + } + } else { + function F() {} // eslint-disable-line no-inner-declarations + return function create(obj, assignProps1, assignProps2, etc) { + var assignArgsList = slice(arguments, 1); + F.prototype = obj; + return assign.apply(this, [new F()].concat(assignArgsList)) + } + } + } + + function make_trim() { + if (String.prototype.trim) { + return function trim(str) { + return String.prototype.trim.call(str) + } + } else { + return function trim(str) { + return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '') + } + } + } + + function bind(obj, fn) { + return function() { + return fn.apply(obj, Array.prototype.slice.call(arguments, 0)) + } + } + + function slice(arr, index) { + return Array.prototype.slice.call(arr, index || 0) + } + + function each(obj, fn) { + pluck(obj, function(val, key) { + fn(val, key); + return false + }); + } + + function map(obj, fn) { + var res = (isList(obj) ? [] : {}); + pluck(obj, function(v, k) { + res[k] = fn(v, k); + return false + }); + return res + } + + function pluck(obj, fn) { + if (isList(obj)) { + for (var i=0; i= 0; i--) { + var key = localStorage$1().key(i); + fn(read(key), key); + } + } + + function remove(key) { + return localStorage$1().removeItem(key) + } + + function clearAll() { + return localStorage$1().clear() + } + + // cookieStorage is useful Safari private browser mode, where localStorage + // doesn't work but cookies do. This implementation is adopted from + // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage + + + var Global$2 = util.Global; + var trim$2 = util.trim; + + var cookieStorage = { + name: 'cookieStorage', + read: read$1, + write: write$1, + each: each$3, + remove: remove$1, + clearAll: clearAll$1, + }; + + var doc = Global$2.document; + + function read$1(key) { + if (!key || !_has(key)) { return null } + var regexpStr = "(?:^|.*;\\s*)" + + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"; + return unescape(doc.cookie.replace(new RegExp(regexpStr), "$1")) + } + + function each$3(callback) { + var cookies = doc.cookie.split(/; ?/g); + for (var i = cookies.length - 1; i >= 0; i--) { + if (!trim$2(cookies[i])) { + continue + } + var kvp = cookies[i].split('='); + var key = unescape(kvp[0]); + var val = unescape(kvp[1]); + callback(val, key); + } + } + + function write$1(key, data) { + if(!key) { return } + doc.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; + } + + function remove$1(key) { + if (!key || !_has(key)) { + return + } + doc.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; + } + + function clearAll$1() { + each$3(function(_, key) { + remove$1(key); + }); + } + + function _has(key) { + return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc.cookie) + } + + var defaults = defaultsPlugin; + + function defaultsPlugin() { + var defaultValues = {}; + + return { + defaults: defaults, + get: get + } + + function defaults(_, values) { + defaultValues = values; + } + + function get(super_fn, key) { + var val = super_fn(); + return (val !== undefined ? val : defaultValues[key]) + } + } + + var namespace = 'expire_mixin'; + + var expire = expirePlugin; + + function expirePlugin() { + var expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace); + + return { + set: expire_set, + get: expire_get, + remove: expire_remove, + getExpiration: getExpiration, + removeExpiredKeys: removeExpiredKeys + } + + function expire_set(super_fn, key, val, expiration) { + if (!this.hasNamespace(namespace)) { + expirations.set(key, expiration); + } + return super_fn() + } + + function expire_get(super_fn, key) { + if (!this.hasNamespace(namespace)) { + _checkExpiration.call(this, key); + } + return super_fn() + } + + function expire_remove(super_fn, key) { + if (!this.hasNamespace(namespace)) { + expirations.remove(key); + } + return super_fn() + } + + function getExpiration(_, key) { + return expirations.get(key) + } + + function removeExpiredKeys(_) { + var keys = []; + this.each(function(val, key) { + keys.push(key); + }); + for (var i=0; i + // This work is free. You can redistribute it and/or modify it + // under the terms of the WTFPL, Version 2 + // For more information see LICENSE.txt or http://www.wtfpl.net/ + // + // For more information, the home page: + // http://pieroxy.net/blog/pages/lz-string/testing.html + // + // LZ-based compression algorithm, version 1.4.4 + var LZString = (function() { + + // private property + var f = String.fromCharCode; + var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"; + var baseReverseDic = {}; + + function getBaseValue(alphabet, character) { + if (!baseReverseDic[alphabet]) { + baseReverseDic[alphabet] = {}; + for (var i=0 ; i>> 8; + buf[i*2+1] = current_value % 256; + } + return buf; + }, + + //decompress from uint8array (UCS-2 big endian format) + decompressFromUint8Array:function (compressed) { + if (compressed===null || compressed===undefined){ + return LZString.decompress(compressed); + } else { + var buf=new Array(compressed.length/2); // 2 bytes per character + for (var i=0, TotalLen=buf.length; i> 1; + } + } else { + value = 1; + for (i=0 ; i> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i=0 ; i> 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + // Add wc to the dictionary. + context_dictionary[context_wc] = context_dictSize++; + context_w = String(context_c); + } + } + + // Output the code for w. + if (context_w !== "") { + if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) { + if (context_w.charCodeAt(0)<256) { + for (i=0 ; i> 1; + } + } else { + value = 1; + for (i=0 ; i> 1; + } + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + delete context_dictionaryToCreate[context_w]; + } else { + value = context_dictionary[context_w]; + for (i=0 ; i> 1; + } + + + } + context_enlargeIn--; + if (context_enlargeIn == 0) { + context_enlargeIn = Math.pow(2, context_numBits); + context_numBits++; + } + } + + // Mark the end of the stream + value = 2; + for (i=0 ; i> 1; + } + + // Flush the last char + while (true) { + context_data_val = (context_data_val << 1); + if (context_data_position == bitsPerChar-1) { + context_data.push(getCharFromInt(context_data_val)); + break; + } + else { context_data_position++; } + } + return context_data.join(''); + }, + + decompress: function (compressed) { + if (compressed == null) { return ""; } + if (compressed == "") { return null; } + return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); }); + }, + + _decompress: function (length, resetValue, getNextValue) { + var dictionary = [], + next, + enlargeIn = 4, + dictSize = 4, + numBits = 3, + entry = "", + result = [], + i, + w, + bits, resb, maxpower, power, + c, + data = {val:getNextValue(0), position:resetValue, index:1}; + + for (i = 0; i < 3; i += 1) { + dictionary[i] = i; + } + + bits = 0; + maxpower = Math.pow(2,2); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + switch (next = bits) { + case 0: + bits = 0; + maxpower = Math.pow(2,8); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + c = f(bits); + break; + case 1: + bits = 0; + maxpower = Math.pow(2,16); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + c = f(bits); + break; + case 2: + return ""; + } + dictionary[3] = c; + w = c; + result.push(c); + while (true) { + if (data.index > length) { + return ""; + } + + bits = 0; + maxpower = Math.pow(2,numBits); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + switch (c = bits) { + case 0: + bits = 0; + maxpower = Math.pow(2,8); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + + dictionary[dictSize++] = f(bits); + c = dictSize-1; + enlargeIn--; + break; + case 1: + bits = 0; + maxpower = Math.pow(2,16); + power=1; + while (power!=maxpower) { + resb = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = resetValue; + data.val = getNextValue(data.index++); + } + bits |= (resb>0 ? 1 : 0) * power; + power <<= 1; + } + dictionary[dictSize++] = f(bits); + c = dictSize-1; + enlargeIn--; + break; + case 2: + return result.join(''); + } + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + if (dictionary[c]) { + entry = dictionary[c]; + } else { + if (c === dictSize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + result.push(entry); + + // Add w+entry[0] to the dictionary. + dictionary[dictSize++] = w + entry.charAt(0); + enlargeIn--; + + w = entry; + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + } + } + }; + return LZString; + })(); + + if( module != null ) { + module.exports = LZString; + } + }); + + var compression = compressionPlugin; + + function compressionPlugin() { + return { + get: get, + set: set, + } + + function get(super_fn, key) { + var val = super_fn(key); + if (!val) { return val } + var decompressed = lzString.decompress(val); + // fallback to existing values that are not compressed + return (decompressed == null) ? val : this._deserialize(decompressed) + } + + function set(super_fn, key, val) { + var compressed = lzString.compress(this._serialize(val)); + super_fn(key, compressed); + } + } + + // sort of persist on the user side + + var storages = [localStorage_1, cookieStorage]; + var plugins = [defaults, expire, events, compression]; + + var localStore = storeEngine.createStore(storages, plugins); + + var Global$3 = util.Global; + + var sessionStorage_1 = { + name: 'sessionStorage', + read: read$2, + write: write$2, + each: each$5, + remove: remove$2, + clearAll: clearAll$2 + }; + + function sessionStorage() { + return Global$3.sessionStorage + } + + function read$2(key) { + return sessionStorage().getItem(key) + } + + function write$2(key, data) { + return sessionStorage().setItem(key, data) + } + + function each$5(fn) { + for (var i = sessionStorage().length - 1; i >= 0; i--) { + var key = sessionStorage().key(i); + fn(read$2(key), key); + } + } + + function remove$2(key) { + return sessionStorage().removeItem(key) + } + + function clearAll$2() { + return sessionStorage().clear() + } + + // session store with watch + + var storages$1 = [sessionStorage_1, cookieStorage]; + var plugins$1 = [defaults, expire]; + + var sessionStore = storeEngine.createStore(storages$1, plugins$1); + + // export store interface + + // export back the raw version for development purposes + var localStore$1 = localStore; + var sessionStore$1 = sessionStore; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray$2 = Array.isArray; + + var global$1$1 = (typeof global$1 !== "undefined" ? global$1 : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$1 = typeof global$1$1 == 'object' && global$1$1 && global$1$1.Object === Object && global$1$1; + + /** Detect free variable `self`. */ + var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')(); + + /** Built-in value references. */ + var Symbol$2 = root$1.Symbol; + + /** Used for built-in method references. */ + var objectProto$f = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$c = objectProto$f.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$2 = objectProto$f.toString; + + /** Built-in value references. */ + var symToStringTag$2 = Symbol$2 ? Symbol$2.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag$1(value) { + var isOwn = hasOwnProperty$c.call(value, symToStringTag$2), + tag = value[symToStringTag$2]; + + try { + value[symToStringTag$2] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString$2.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag$2] = tag; + } else { + delete value[symToStringTag$2]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1$1 = objectProto$1$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString$1(value) { + return nativeObjectToString$1$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag$1 = '[object Null]', + undefinedTag$1 = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1$1 = Symbol$2 ? Symbol$2.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag$1(value) { + if (value == null) { + return value === undefined ? undefinedTag$1 : nullTag$1; + } + return (symToStringTag$1$1 && symToStringTag$1$1 in Object(value)) + ? getRawTag$1(value) + : objectToString$1(value); + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg$1(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** Built-in value references. */ + var getPrototype$1 = overArg$1(Object.getPrototypeOf, Object); + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$1(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var objectTag$4 = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto$3 = Function.prototype, + objectProto$2$1 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$3 = funcProto$3.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1$1 = objectProto$2$1.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString$1 = funcToString$3.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject$1(value) { + if (!isObjectLike$1(value) || baseGetTag$1(value) != objectTag$4) { + return false; + } + var proto = getPrototype$1(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString$3.call(Ctor) == objectCtorString$1; + } + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$2 = Symbol$2 ? Symbol$2.prototype : undefined, + symbolToString$1 = symbolProto$2 ? symbolProto$2.toString : undefined; + + /** `Object#toString` result references. */ + var stringTag$3 = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString$2(value) { + return typeof value == 'string' || + (!isArray$2(value) && isObjectLike$1(value) && baseGetTag$1(value) == stringTag$3); + } + + // bunch of generic helpers + + /** + * DIY in Array + * @param {array} arr to check from + * @param {*} value to check against + * @return {boolean} true on found + */ + var inArray$1 = function (arr, value) { return !!arr.filter(function (a) { return a === value; }).length; }; + + /** + * @param {object} obj for search + * @param {string} key target + * @return {boolean} true on success + */ + var isKeyInObject$2 = function(obj, key) { + var keys = Object.keys(obj); + return inArray$1(keys, key) + }; + + /** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ + var timestamp = function (sec) { + if ( sec === void 0 ) { sec = false; } + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; + }; + + /** + * @return {object} _cb as key with timestamp + */ + var cacheBurst = function () { return ({ _cb: timestamp() }); }; + + // the core stuff to id if it's calling with jsonql + var DATA_KEY$1 = 'data'; + var ERROR_KEY$1 = 'error'; + + // @TODO remove this is not in use + // export const CLIENT_CONFIG_FILE = '.clients.json'; + // export const CONTRACT_CONFIG_FILE = 'jsonql-contract-config.js'; + // type of resolvers + var QUERY_NAME = 'query'; + var MUTATION_NAME = 'mutation'; + var SOCKET_NAME = 'socket'; + // for calling the mutation + var PAYLOAD_PARAM_NAME = 'payload'; + var CONDITION_PARAM_NAME = 'condition'; + var QUERY_ARG_NAME = 'args'; + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser$1 = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode$1 = function () { + try { + if (!isBrowser$1() && global$1$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI$1() { + if (isBrowser$1()) { + return 'browser' + } + if (isNode$1()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError$1 = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var arguments$1 = arguments; + + var args = [], len = arguments.length; + while ( len-- ) { args[ len ] = arguments$1[ len ]; } + + Error.apply(this, args); + } + + if ( Error ) { JsonqlBaseError.__proto__ = Error; } + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI$1() + }; + + return JsonqlBaseError; + }(Error)); + + // custom validation error class + // when validaton failed + var JsonqlValidationError$1 = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var arguments$1 = arguments; + + var args = [], len = arguments.length; + while ( len-- ) { args[ len ] = arguments$1[ len ]; } + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) { JsonqlValidationError.__proto__ = JsonqlBaseError; } + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; + }(JsonqlBaseError$1)); + + // split the contract into the node side and the generic side + /** + * Check if the json is a contract file or not + * @param {object} contract json object + * @return {boolean} true + */ + function checkIsContract(contract) { + return isPlainObject$1(contract) + && ( + isKeyInObject$2(contract, QUERY_NAME) + || isKeyInObject$2(contract, MUTATION_NAME) + || isKeyInObject$2(contract, SOCKET_NAME) + ) + } + + /** + * @param {*} args arguments to send + *@return {object} formatted payload + */ + var formatPayload = function (args) { + var obj; + + return ( + ( obj = {}, obj[QUERY_ARG_NAME] = args, obj ) + ); + }; + + /** + * Get name from the payload (ported back from jsonql-koa) + * @param {*} payload to extract from + * @return {string} name + */ + function getNameFromPayload(payload) { + return Object.keys(payload)[0] + } + + /** + * @param {string} resolverName name of function + * @param {array} [args=[]] from the ...args + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ + function createQuery(resolverName, args, jsonp) { + var obj; + + if ( args === void 0 ) { args = []; } + if ( jsonp === void 0 ) { jsonp = false; } + if (isString$2(resolverName) && isArray$2(args)) { + var payload = formatPayload(args); + if (jsonp === true) { + return payload; + } + return ( obj = {}, obj[resolverName] = payload, obj ) + } + throw new JsonqlValidationError$1("[createQuery] expect resolverName to be string and args to be array!", { resolverName: resolverName, args: args }) + } + + /** + * @param {string} resolverName name of function + * @param {*} payload to send + * @param {object} [condition={}] for what + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ + function createMutation(resolverName, payload, condition, jsonp) { + var obj; + + if ( condition === void 0 ) { condition = {}; } + if ( jsonp === void 0 ) { jsonp = false; } + var _payload = {}; + _payload[PAYLOAD_PARAM_NAME] = payload; + _payload[CONDITION_PARAM_NAME] = condition; + if (jsonp === true) { + return _payload; + } + if (isString$2(resolverName)) { + return ( obj = {}, obj[resolverName] = _payload, obj ) + } + throw new JsonqlValidationError$1("[createMutation] expect resolverName to be string!", { resolverName: resolverName, payload: payload, condition: condition }) + } + + // ported from http-client + + /** + * handle the return data + * @param {object} result return from server + * @return {object} strip the data part out, or if the error is presented + */ + var resultHandler = function (result) { return ( + (isKeyInObject$2(result, DATA_KEY$1) && !isKeyInObject$2(result, ERROR_KEY$1)) ? result[DATA_KEY$1] : result + ); }; + + // exportfor ES modules + + // alias + var isContract = checkIsContract; + + // take only the module part which is what we use here + /** + * @param {object} jsonqlInstance the init instance of jsonql client + * @param {object} contract the static contract + * @return {object} contract may be from server + */ + var getContractFromConfig = function(jsonqlInstance, contract) { + if ( contract === void 0 ) contract = {}; + + if (isContract(contract)) { + return Promise.resolve(contract) + } + return jsonqlInstance.getContract() + }; + + // export some constants as well + // since it's only use here there is no point of adding it to the constants module + // or may be we add it back later + var ENDPOINT_TABLE = 'endpoint'; + var USERDATA_TABLE = 'userdata'; + + /** + * The code was extracted from: + * https://github.com/davidchambers/Base64.js + */ + + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + + InvalidCharacterError.prototype = new Error(); + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + function polyfill (input) { + var str = String(input).replace(/=+$/, ''); + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + } + + + var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; + + function b64DecodeUnicode(str) { + return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { + var code = p.charCodeAt(0).toString(16).toUpperCase(); + if (code.length < 2) { + code = '0' + code; + } + return '%' + code; + })); + } + + var base64_url_decode = function(str) { + var output = str.replace(/-/g, "+").replace(/_/g, "/"); + switch (output.length % 4) { + case 0: + break; + case 2: + output += "=="; + break; + case 3: + output += "="; + break; + default: + throw "Illegal base64url string!"; + } + + try{ + return b64DecodeUnicode(output); + } catch (err) { + return atob(output); + } + }; + + function InvalidTokenError(message) { + this.message = message; + } + + InvalidTokenError.prototype = new Error(); + InvalidTokenError.prototype.name = 'InvalidTokenError'; + + var lib = function (token,options) { + if (typeof token !== 'string') { + throw new InvalidTokenError('Invalid token specified'); + } + + options = options || {}; + var pos = options.header === true ? 0 : 1; + try { + return JSON.parse(base64_url_decode(token.split('.')[pos])); + } catch (e) { + throw new InvalidTokenError('Invalid token specified: ' + e.message); + } + }; + + var InvalidTokenError_1 = InvalidTokenError; + lib.InvalidTokenError = InvalidTokenError_1; + + // bunch of generic helpers + + /** + * @param {string} name the name part after the : + * @param {string} baseName the base before the : + */ + var getDebug = function (name, baseName) { + if ( baseName === void 0 ) baseName = 'jsonql'; + + return debug$1(baseName).extend(name) + }; + + /** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ + var timestamp$1 = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; + }; + + // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js + var performance = global$1.performance || {}; + var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + + // koa specific methods + var debug = getDebug("koa", "jsonql-utils"); + + // when the user is login with the jwt + /** + * We only check the nbf and exp + * @param {object} token for checking + * @return {object} token on success + */ + function validate(token) { + var start = token.iat || timestamp$1(); + // we only check the exp for the time being + if (token.exp) { + if (start >= token.exp) { + var expired = new Date(token.exp).toISOString(); + throw new JsonqlError(("Token has expired on " + expired), token) + } + } + return token; + } + + /** + * The browser client version it has far fewer options and it doesn't verify it + * because it couldn't this is the job for the server + * @TODO we need to add some extra proessing here to check for the exp field + * @param {string} token to decrypted + * @return {object} decrypted object + */ + function jwtDecode(token) { + if (isString$1(token)) { + var t = lib(token); + return validate(t) + } + throw new JsonqlError('Token must be a string!') + } + + var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; + + var appProps = { + algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), + expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), + notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), + audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), + subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), + issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), + noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), + header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), + keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), + mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) + }; + + // base HttpClass + + // extract the one we need + var POST = API_REQUEST_METHODS[0]; + var PUT = API_REQUEST_METHODS[1]; + + var _log = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.console) { + Reflect.apply(console.log, null, args); + } + } catch(e) {} + }; + + var HttpClass = function HttpClass(opts) { + // change the way how we init Fly + // flyio now become external depedencies and it makes it easier to switch + // @BUG should we run test to check if we have the windows object? + _log(opts); + this.fly = opts.Fly ? new opts.Fly() : new Fly(); + // to a different environment like WeChat mini app + this.opts = opts; + this.extraHeader = {}; + // @1.2.1 for adding query to the call on the fly + this.extraParams = {}; + // this.log('start up opts', opts); + this.reqInterceptor(); + this.resInterceptor(); + }; + + var prototypeAccessors = { headers: { configurable: true } }; + + // set headers for that one call + prototypeAccessors.headers.set = function (header) { + this.extraHeader = header; + }; + + /** + * Create the reusage request method + * @param {object} payload jsonql payload + * @param {object} options extra options add the request + * @param {object} headers extra headers add to the call + * @return {object} the fly request instance + */ + HttpClass.prototype.request = function request (payload, options, headers) { + var obj; + + if ( options === void 0 ) options = {}; + if ( headers === void 0 ) headers = {}; + this.headers = headers; + var params = merge({}, cacheBurst(), this.extraParams); + // @TODO need to add a jsonp url and payload + if (this.opts.enableJsonp) { + var resolverName = getNameFromPayload(payload); + params = merge({}, params, ( obj = {}, obj[JSONP_CALLBACK_NAME] = resolverName, obj )); + payload = payload[resolverName]; + } + return this.fly.request( + this.jsonqlEndpoint, + payload, + merge({}, { method: POST, params: params }, options) + ) + }; + + /** + * This will replace the create baseRequest method + * + */ + HttpClass.prototype.reqInterceptor = function reqInterceptor () { + var this$1 = this; + + this.fly.interceptors.request.use( + function (req) { + var headers = this$1.getHeaders(); + this$1.log('request interceptor call', headers); + + for (var key in headers) { + req.headers[key] = headers[key]; + } + return req; + } + ); + }; + + // @TODO + HttpClass.prototype.processJsonp = function processJsonp (result) { + return resultHandler(result) + }; + + /** + * This will be replacement of the first then call + * + */ + HttpClass.prototype.resInterceptor = function resInterceptor () { + var this$1 = this; + + var self = this; + var jsonp = self.opts.enableJsonp; + this.fly.interceptors.response.use( + function (res) { + this$1.log('response interceptor call'); + self.cleanUp(); + // now more processing here + // there is a problem if we throw the result.error here + // the original data is lost, so we need to do what we did before + // deal with that error in the first then instead + var result = isString$1(res.data) ? JSON.parse(res.data) : res.data; + if (jsonp) { + return self.processJsonp(result) + } + return resultHandler(result) + }, + // this get call when it's not 200 + function (err) { + self.cleanUp(); + console.error(err); + throw new JsonqlServerError('Server side error', err) + } + ); + }; + + /** + * Get the headers inject into the call + * @return {object} headers + */ + HttpClass.prototype.getHeaders = function getHeaders () { + if (this.opts.enableAuth) { + return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader) + } + return merge({}, DEFAULT_HEADER, this.extraHeader) + }; + + /** + * Post http call operation to clean up things we need + */ + HttpClass.prototype.cleanUp = function cleanUp () { + this.extraHeader = {}; + this.extraParams = {}; + }; + + /** + * GET for contract only + */ + HttpClass.prototype.get = function get () { + var this$1 = this; + + if (this.opts.showContractDesc) { + this.extraParams = merge({}, this.extraParams, SHOW_CONTRACT_DESC_PARAM); + } + return this.request({}, {method: 'GET'}, this.contractHeader) + .then(clientErrorsHandler) + .then(function (result) { + this$1.log('get contract result', result); + // when refresh the window the result is different! + // @TODO need to check the Koa side about why is that + // also it should set a flag if we want the description or not + if (result.cache && result.contract) { + return result.contract; + } + // just the normal result + return result + }) + }; + + /** + * POST to server - query + * @param {object} name of the resolver + * @param {array} args arguments + * @return {object} promise resolve to the resolver return + */ + HttpClass.prototype.query = function query (name, args) { + if ( args === void 0 ) args = []; + + return this.request(createQuery(name, args)) + .then(clientErrorsHandler) + }; + + /** + * PUT to server - mutation + * @param {string} name of resolver + * @param {object} payload what it said + * @param {object} conditions what it said + * @return {object} promise resolve to the resolver return + */ + HttpClass.prototype.mutation = function mutation (name, payload, conditions) { + if ( payload === void 0 ) payload = {}; + if ( conditions === void 0 ) conditions = {}; + + return this.request(createMutation(name, payload, conditions), {method: PUT}) + .then(clientErrorsHandler) + }; + + Object.defineProperties( HttpClass.prototype, prototypeAccessors ); + + // all the contract related methods will be here + + // export + var ContractClass = /*@__PURE__*/(function (HttpClass) { + function ContractClass(opts) { + HttpClass.call(this, opts); + } + + if ( HttpClass ) ContractClass.__proto__ = HttpClass; + ContractClass.prototype = Object.create( HttpClass && HttpClass.prototype ); + ContractClass.prototype.constructor = ContractClass; + + var prototypeAccessors = { contractHeader: { configurable: true } }; + + /** + * return the contract public api + * @return {object} contract + */ + ContractClass.prototype.getContract = function getContract () { + var contracts = this.readContract(); + this.log('getContract first call', contracts); + if (contracts && Array.isArray(contracts)) { + var contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]; + if (contract) { + return Promise.resolve(contract) + } + } + return this.get() + .then( this.storeContract.bind(this) ) + }; + + /** + * We are changing the way how to auth to get the contract.json + * Instead of in the url, we will be putting that key value in the header + * @return {object} header + */ + prototypeAccessors.contractHeader.get = function () { + var base = {}; + if (this.opts.contractKey !== false) { + base[this.opts.contractKeyName] = this.opts.contractKey; + } + return base; + }; + + /** + * Save the contract to local store + * @param {object} contract to save + * @return {object|boolean} false when its not a contract or contract on OK + */ + ContractClass.prototype.storeContract = function storeContract (contract) { + // first need to check if the contract is a contract + if (!isContract(contract)) { + throw new JsonqlValidationError("Contract is malformed!") + //return false; + } + var args = [contract]; + if (this.opts.contractExpired) { + var expired = parseFloat(this.opts.contractExpired); + if (!isNaN(expired) && expired > 0) { + args.push(expired); + } + } + // calling the setter + this.jsonqlContract = args; + // return it + this.log('storeContract return result', contract); + return contract; + }; + + /** + * return the contract from options or localStore + * @return {object} contract + */ + ContractClass.prototype.readContract = function readContract () { + var contract = isContract(this.opts.contract); + return contract ? this.opts.contract : localStore$1.get(this.opts.storageKey) + }; + + Object.defineProperties( ContractClass.prototype, prototypeAccessors ); + + return ContractClass; + }(HttpClass)); + + // this is the new auth class that integrate with the jsonql-jwt + // export + var AuthClass = /*@__PURE__*/(function (ContractClass) { + function AuthClass(opts) { + ContractClass.call(this, opts); + if (opts.enableAuth && opts.useJwt) { + this.setDecoder = jwtDecode; + } + } + + if ( ContractClass ) AuthClass.__proto__ = ContractClass; + AuthClass.prototype = Object.create( ContractClass && ContractClass.prototype ); + AuthClass.prototype.constructor = AuthClass; + + var prototypeAccessors = { userdata: { configurable: true },rawAuthToken: { configurable: true },setDecoder: { configurable: true } }; + + /** + * Getter to get the login userdata + * @return {mixed} userdata + */ + prototypeAccessors.userdata.get = function () { + return this.jsonqlUserdata; // see base-cls + }; + + /** + * Return the token from session store + * @return {string} token + */ + prototypeAccessors.rawAuthToken.get = function () { + // this should return from the base + return this.jsonqlToken; // see base-cls + }; + + /** + * Setter to add a decoder when retrieve user token + * @param {function} d a decoder + */ + prototypeAccessors.setDecoder.set = function (d) { + if (typeof d === 'function') { + this.decoder = d; + } + }; + + /** + * Setter after login success + * @TODO this move to a new class to handle multiple login + * @param {string} token to store + * @return {*} success store + */ + AuthClass.prototype.storeToken = function storeToken (token) { + return this.jsonqlToken = token; + }; + + /** + * for overwrite + * @param {string} token stored token + * @return {string} token + */ + AuthClass.prototype.decoder = function decoder (token) { + return token; + }; + + /** + * Construct the auth header + * @return {object} header + */ + AuthClass.prototype.getAuthHeader = function getAuthHeader () { + var obj; + + var token = this.rawAuthToken; + return token ? ( obj = {}, obj[this.opts.AUTH_HEADER] = (BEARER + " " + token), obj ) : {}; + }; + + Object.defineProperties( AuthClass.prototype, prototypeAccessors ); + + return AuthClass; + }(ContractClass)); + + // this the core of the internal storage management + + // This class will only focus on the storage system + var JsonqlBaseClient = /*@__PURE__*/(function (AuthCls) { + function JsonqlBaseClient(opts, Fly) { + if ( Fly === void 0 ) Fly = null; + + if (Fly) { + opts.Fly = Fly; + } + AuthCls.call(this, opts); + } + + if ( AuthCls ) JsonqlBaseClient.__proto__ = AuthCls; + JsonqlBaseClient.prototype = Object.create( AuthCls && AuthCls.prototype ); + JsonqlBaseClient.prototype.constructor = JsonqlBaseClient; + + var prototypeAccessors = { storeIt: { configurable: true },jsonqlEndpoint: { configurable: true },jsonqlContract: { configurable: true },jsonqlToken: { configurable: true },jsonqlUserdata: { configurable: true } }; + + // @TODO + prototypeAccessors.storeIt.set = function (args) { + console.info('storeIt', args); + // the args MUST contain [0] the key , [1] the content [2] optional expired in + if (isArray$1(args) && args.length >= 2) { + Reflect.apply(localStore$1.set, localStore$1, args); + } + throw new JsonqlValidationError("Expect argument to be array and least 2 items!") + }; + + // this table index key will drive the contract + // also it should not allow to change dynamicly + // because this is how different client can id itself + // OK this could be self manage because when init a new client + // it will add a new endpoint and we will know if they are the same or not + // but the check here + prototypeAccessors.jsonqlEndpoint.set = function (endpoint) { + var urls = localStore$1.get(ENDPOINT_TABLE) || []; + // should check if this url already existed? + if (!inArray$1(urls, endpoint)) { + urls.push(endpoint); + this.storeId = [ENDPOINT_TABLE, urls]; + this[ENDPOINT_TABLE + 'Index'] = urls.length - 1; + } + }; + + // by the time it call the save contract already been checked + prototypeAccessors.jsonqlContract.set = function (args) { + var key = this.opts.storageKey; + var _args = [ key ]; + var contract = args[0]; + var expired = args[1]; + // get the endpoint index + var contracts = localStore$1.get(key) || []; + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + _args.push(contracts); + if (expired) { + _args.push(expired); + } + if (this.opts.keepContract) { + this.storeIt = _args; + } + }; + + /** + * save token + * @param {string} token to store + * @return {string|boolean} false on failed + */ + prototypeAccessors.jsonqlToken.set = function (token) { + var key = CREDENTIAL_STORAGE_KEY; + var tokens = localStorage.get(key) || []; + if (!inArray$1(tokens, token)) { + var index = tokens.length - 1; + tokens[ index ] = token; + this[key + 'Index'] = index; + var args = [key, tokens]; + if (this.opts.tokenExpired) { + var expired = parseFloat(this.opts.tokenExpired); + if (!isNaN(expired) && expired > 0) { + var ts = timestamp(); + args.push( ts + parseFloat(expired) ); + } + } + this.storeIt = args; + // now decode it and store in the userdata + this.jsonqlUserdata = this.decoder(token); + return token; + } + return false; + }; + + /** + * this one will use the sessionStore + * basically we hook this onto the token store and decode it to store here + */ + prototypeAccessors.jsonqlUserdata.set = function (userdata) { + var args = [USERDATA_TABLE, userdata]; + if (userdata.exp) { + args.push(userdata.exp); + } + return Reflect.apply(localStore$1.set, localStore$1, args) + }; + + /** + * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point + * @return {string} the end point to call + */ + prototypeAccessors.jsonqlEndpoint.get = function () { + var urls = localStore$1.get(ENDPOINT_TABLE); + if (!urls) { + var ref = this.opts; + var hostname = ref.hostname; + var jsonqlPath = ref.jsonqlPath; + var url = [hostname, jsonqlPath].join('/'); + this.jsonqlEndpoint = url; + return url; + } + return urls[this[ENDPOINT_TABLE + 'Index']] + }; + + /** + * If already stored then return it by the end point index + * or false when there is none + * 1.2.0 start using the keepContract option (replace the useLocalStorage) + * @return {object|boolean} as described above + */ + prototypeAccessors.jsonqlContract.get = function () { + var key = this.opts.storageKey; + var contracts = localStore$1.get(key) || []; + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false + }; + + /** + * Jsonql token getter + * @return {string|boolean} false when failed + */ + prototypeAccessors.jsonqlToken.get = function () { + var key = CREDENTIAL_STORAGE_KEY; + var tokens = localStorage.get(key); + if (tokens) { + return tokens[ this[key + 'Index'] ] + } + return false; + }; + + /** + * this one store in the session store + * get login userdata decoded jwt + * @return {object|null} + */ + prototypeAccessors.jsonqlUserdata.get = function () { + return sessionStore$1.get(USERDATA_TABLE) + }; + + /** + * simple log + */ + JsonqlBaseClient.prototype.log = function log () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + if (this.opts.debugOn === true) { + Reflect.apply(console.info, console, args); + } + }; + + Object.defineProperties( JsonqlBaseClient.prototype, prototypeAccessors ); + + return JsonqlBaseClient; + }(AuthClass)); + + // export interface + + // breaking out the inner methods generator in here + + /** + * generate authorisation specific methods + * @param {object} jsonqlInstance instance of this + * @param {string} name of method + * @param {object} opts configuration + * @param {object} contract to match + * @return {function} for use + */ + var authMethodGenerator = function (jsonqlInstance, name, opts, contract) { + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var params = contract.auth[name].params; + var values = params.map(function (p, i) { return args[i]; }); + var header = args[params.length] || {}; + return validateAsync$1(args, params) + .then(function () { return jsonqlInstance + .query + .apply(jsonqlInstance, [name, values, header]); } + ) + .catch(finalCatch) + } + }; + + /** + * Here just generate the methods calls + * @param {object} jsonqlInstance what it said + * @param {object} ee event emitter + * @param {object} config configuration + * @param {object} contract the map + * @return {object} with mapped methods + */ + function methodsGenerator(jsonqlInstance, ee, config, contract) { + var obj = {query: {}, mutation: {}}; + // process the query first + var loop = function ( queryFn ) { + // to keep it clean we use a param to id the auth method + // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn; + // generate the query method + obj.query[queryFn] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var params = contract.query[queryFn].params; + var _args = params.map(function (param, i) { return args[i]; }); + // debug('query', queryFn, _params); + // @TODO this need to change + // the +1 parameter is the extra headers we want to pass + var header = args[params.length] || {}; + // @TODO validate against the type + return validateAsync$1(_args, params) + .then(function () { return jsonqlInstance + .query + .apply(jsonqlInstance, [queryFn, _args, header]); } + ) + .catch(finalCatch) + }; + }; + + for (var queryFn in contract.query) loop( queryFn ); + // process the mutation, the reason the mutation has a fixed number of parameters + // there is only the payload, and conditions parameters + // plus a header at the end + var loop$1 = function ( mutationFn ) { + obj.mutation[mutationFn] = function (payload, conditions, header) { + if ( header === void 0 ) header = {}; + + var args = [payload, conditions]; + var params = contract.mutation[mutationFn].params; + return validateAsync$1(args, params) + .then(function () { return jsonqlInstance + .mutation + .apply(jsonqlInstance, [mutationFn, payload, conditions, header]); } + ) + .catch(finalCatch) + }; + }; + + for (var mutationFn in contract.mutation) loop$1( mutationFn ); + // there is only one call issuer we want here + if (config.enableAuth && contract.auth) { + obj.auth = {}; // v1.3.1 add back the auth prop name + var loginHandlerName = config.loginHandlerName; + var logoutHandlerName = config.logoutHandlerName; + if (contract.auth[loginHandlerName]) { + // changing to the name the config specify + obj.auth[loginHandlerName] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract); + return fn.apply(null, args) + .then(jsonqlInstance.postLoginAction) + .then(function (token) { + ee.$trigger(ISSUER_NAME, token); + return token; + }) + }; + } + if (contract.auth[logoutHandlerName]) { + obj.auth[logoutHandlerName] = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract); + return fn.apply(null, args) + .then(jsonqlInstance.postLogoutAction) + .then(function (r) { + ee.$trigger(LOGOUT_NAME, r); + return r; + }) + }; + } else { + obj.auth[logoutHandlerName] = function () { + jsonqlInstance.postLogoutAction(KEY_WORD); + ee.$trigger(LOGOUT_NAME, KEY_WORD); + }; + } + } + return obj; + } + + // Generate the resolver for developer to use + + /** + * @param {object} jsonqlInstance jsonql class instance + * @param {object} config options + * @param {object} contract the contract + * @param {object} ee eventEmitter + * @return {object} constructed functions call + */ + var generator = function (jsonqlInstance, config, contract, ee) { + // V1.3.0 - now everything wrap inside this method + var obj = methodsGenerator(jsonqlInstance, ee, config, contract); + // create the rest of the methods + if (config.enableAuth) { + /** + * new method to allow retrieve the current login user data + * @return {*} userdata + */ + obj.userdata = function () { return jsonqlInstance.userdata; }; + } + // allow getting the token for valdiate agains the socket + obj.getToken = function () { return jsonqlInstance.rawAuthToken; }; + // this will pass to the ws-client if needed + // obj.eventEmitter = ee; + // this will require a param + if (config.exposeContract) { + obj.getContract = function () { return jsonqlInstance.get(); }; + } + // this is for the ws to use later + obj.eventEmitter = ee; + obj.version = '0.1.0'; + // output + return obj; + }; + + // all the client configuration options here + var constProps = { + contract: false, + MUTATION_ARGS: ['name', 'payload', 'conditions'], // this seems wrong? + CONTENT_TYPE: CONTENT_TYPE, + BEARER: BEARER, + AUTH_HEADER: AUTH_HEADER + }; + + // grab the localhost name and put into the hostname as default + var getHostName = function () { return ( + [window.location.protocol, window.location.host].join('//') + ); }; + + var appProps$1 = { + + hostname: createConfig$1(getHostName(), [STRING_TYPE]), // required the hostname + jsonqlPath: createConfig$1(JSONQL_PATH, [STRING_TYPE]), // The path on the server + + loginHandlerName: createConfig$1(ISSUER_NAME, [STRING_TYPE]), + logoutHandlerName: createConfig$1(LOGOUT_NAME, [STRING_TYPE]), + // add to koa v1.3.0 - this might remove in the future + enableJsonp: createConfig$1(false, [BOOLEAN_TYPE]), + enableAuth: createConfig$1(false, [BOOLEAN_TYPE]), + // enable useJwt by default + useJwt: createConfig$1(true, [BOOLEAN_TYPE]), + + // the header + // v1.2.0 we are using this option during the dev + // so it won't save anything to the localstorage and fetch a new contract + // whenever the browser reload + useLocalstorage: createConfig$1(true, [BOOLEAN_TYPE]), // should we store the contract into localStorage + storageKey: createConfig$1(CLIENT_STORAGE_KEY, [STRING_TYPE]),// the key to use when store into localStorage + authKey: createConfig$1(CLIENT_AUTH_KEY, [STRING_TYPE]),// the key to use when store into the sessionStorage + contractExpired: createConfig$1(0, [NUMBER_TYPE]),// -1 always fetch contract, + // 0 never expired, + // > 0 then compare the timestamp with the current one to see if we need to get contract again + // useful during development + keepContract: createConfig$1(true, [BOOLEAN_TYPE]), + exposeContract: createConfig$1(false, [BOOLEAN_TYPE]), + // @1.2.1 new option for the contract-console to fetch the contract with description + showContractDesc: createConfig$1(false, [BOOLEAN_TYPE]), + contractKey: createConfig$1(false, [BOOLEAN_TYPE]), // if the server side is lock by the key you need this + contractKeyName: createConfig$1(CONTRACT_KEY_NAME, [STRING_TYPE]), // same as above they go in pairs + enableTimeout: createConfig$1(false, [BOOLEAN_TYPE]), // @TODO + timeout: createConfig$1(5000, [NUMBER_TYPE]), // 5 seconds + returnInstance: createConfig$1(false, [BOOLEAN_TYPE]), + allowReturnRawToken: createConfig$1(false, [BOOLEAN_TYPE]), + debugOn: createConfig$1(false, [BOOLEAN_TYPE]) + }; + + // we must ensure the user passing the correct options + + function checkOptionsAsync$1(config) { + var contract = config.contract; + return checkConfigAsync$1(config, appProps$1, constProps) + .then(function (opts) { + opts.contract = contract; + return opts; + }) + } + + // This is for the sync version therefore we don't need to care about the contract options + + function checkOptions(config) { + return checkConfig$1(config, appProps$1, constProps) + } + + // this is new for the flyio and normalize the name from now on + + /** + * Main interface for jsonql fetch api + * @param {object} config + * @param {object} Fly this is really pain in the backside ... long story + * @return {object} jsonql client + */ + function jsonqlAsync(ee, config, Fly) { + if ( config === void 0 ) config = {}; + if ( Fly === void 0 ) Fly = null; + + return checkOptionsAsync$1(config) + .then(function (opts) { return ( + { + baseClient: new JsonqlBaseClient(opts, Fly), + opts: opts + } + ); }) + .then( function (ref) { + var baseClient = ref.baseClient; + var opts = ref.opts; + + return ( + getContractFromConfig(baseClient, opts.contract) + .then(function (contract) { return generator(baseClient, opts, contract, ee); } + ) + ); + } + ) + } + + var NB_EVENT_SERVICE_PRIVATE_STORE = new WeakMap(); + var NB_EVENT_SERVICE_PRIVATE_LAZY = new WeakMap(); + + /** + * generate a 32bit hash based on the function.toString() + * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery + * @param {string} s the converted to string function + * @return {string} the hashed function string + */ + function hashCode(s) { + return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0) + } + + // making all the functionality on it's own + // import { WatchClass } from './watch' + + var SuspendClass = function SuspendClass() { + // suspend, release and queue + this.__suspend__ = null; + this.queueStore = new Set(); + /* + this.watch('suspend', function(value, prop, oldValue) { + this.logger(`${prop} set from ${oldValue} to ${value}`) + // it means it set the suspend = true then release it + if (oldValue === true && value === false) { + // we want this happen after the return happens + setTimeout(() => { + this.release() + }, 1) + } + return value; // we need to return the value to store it + }) + */ + }; + + var prototypeAccessors$1 = { $suspend: { configurable: true },$queues: { configurable: true } }; + + /** + * setter to set the suspend and check if it's boolean value + * @param {boolean} value to trigger + */ + prototypeAccessors$1.$suspend.set = function (value) { + var this$1 = this; + + if (typeof value === 'boolean') { + var lastValue = this.__suspend__; + this.__suspend__ = value; + this.logger('($suspend)', ("Change from " + lastValue + " --> " + value)); + if (lastValue === true && value === false) { + setTimeout(function () { + this$1.release(); + }, 1); + } + } else { + throw new Error("$suspend only accept Boolean value!") + } + }; + + /** + * queuing call up when it's in suspend mode + * @param {any} value + * @return {Boolean} true when added or false when it's not + */ + SuspendClass.prototype.$queue = function $queue () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + if (this.__suspend__ === true) { + this.logger('($queue)', 'added to $queue', args); + // there shouldn't be any duplicate ... + this.queueStore.add(args); + } + return this.__suspend__; + }; + + /** + * a getter to get all the store queue + * @return {array} Set turn into Array before return + */ + prototypeAccessors$1.$queues.get = function () { + var size = this.queueStore.size; + this.logger('($queues)', ("size: " + size)); + if (size > 0) { + return Array.from(this.queueStore) + } + return [] + }; + + /** + * Release the queue + * @return {int} size if any + */ + SuspendClass.prototype.release = function release () { + var this$1 = this; + + var size = this.queueStore.size; + this.logger('(release)', ("Release was called " + size)); + if (size > 0) { + var queue = Array.from(this.queueStore); + this.queueStore.clear(); + this.logger('queue', queue); + queue.forEach(function (args) { + this$1.logger(args); + Reflect.apply(this$1.$trigger, this$1, args); + }); + this.logger(("Release size " + (this.queueStore.size))); + } + }; + + Object.defineProperties( SuspendClass.prototype, prototypeAccessors$1 ); + + // break up the main file because its getting way too long + + var NbEventServiceBase = /*@__PURE__*/(function (SuspendClass) { + function NbEventServiceBase(config) { + if ( config === void 0 ) config = {}; + + SuspendClass.call(this); + if (config.logger && typeof config.logger === 'function') { + this.logger = config.logger; + } + this.keep = config.keep; + // for the $done setter + this.result = config.keep ? [] : null; + // we need to init the store first otherwise it could be a lot of checking later + this.normalStore = new Map(); + this.lazyStore = new Map(); + } + + if ( SuspendClass ) NbEventServiceBase.__proto__ = SuspendClass; + NbEventServiceBase.prototype = Object.create( SuspendClass && SuspendClass.prototype ); + NbEventServiceBase.prototype.constructor = NbEventServiceBase; + + var prototypeAccessors = { normalStore: { configurable: true },lazyStore: { configurable: true } }; + + /** + * validate the event name(s) + * @param {string[]} evt event name + * @return {boolean} true when OK + */ + NbEventServiceBase.prototype.validateEvt = function validateEvt () { + var this$1 = this; + var evt = [], len = arguments.length; + while ( len-- ) evt[ len ] = arguments[ len ]; + + evt.forEach(function (e) { + if (typeof e !== 'string') { + this$1.logger('(validateEvt)', e); + throw new Error("event name must be string type!") + } + }); + return true; + }; + + /** + * Simple quick check on the two main parameters + * @param {string} evt event name + * @param {function} callback function to call + * @return {boolean} true when OK + */ + NbEventServiceBase.prototype.validate = function validate (evt, callback) { + if (this.validateEvt(evt)) { + if (typeof callback === 'function') { + return true; + } + } + throw new Error("callback required to be function type!") + }; + + /** + * Check if this type is correct or not added in V1.5.0 + * @param {string} type for checking + * @return {boolean} true on OK + */ + NbEventServiceBase.prototype.validateType = function validateType (type) { + var types = ['on', 'only', 'once', 'onlyOnce']; + return !!types.filter(function (t) { return type === t; }).length; + }; + + /** + * Run the callback + * @param {function} callback function to execute + * @param {array} payload for callback + * @param {object} ctx context or null + * @return {void} the result store in $done + */ + NbEventServiceBase.prototype.run = function run (callback, payload, ctx) { + this.logger('(run)', callback, payload, ctx); + this.$done = Reflect.apply(callback, ctx, this.toArray(payload)); + }; + + /** + * Take the content out and remove it from store id by the name + * @param {string} evt event name + * @param {string} [storeName = lazyStore] name of store + * @return {object|boolean} content or false on not found + */ + NbEventServiceBase.prototype.takeFromStore = function takeFromStore (evt, storeName) { + if ( storeName === void 0 ) storeName = 'lazyStore'; + + var store = this[storeName]; // it could be empty at this point + if (store) { + this.logger('(takeFromStore)', storeName, store); + if (store.has(evt)) { + var content = store.get(evt); + this.logger('(takeFromStore)', ("has " + evt), content); + store.delete(evt); + return content; + } + return false; + } + throw new Error((storeName + " is not supported!")) + }; + + /** + * The add to store step is similar so make it generic for resuse + * @param {object} store which store to use + * @param {string} evt event name + * @param {spread} args because the lazy store and normal store store different things + * @return {array} store and the size of the store + */ + NbEventServiceBase.prototype.addToStore = function addToStore (store, evt) { + var args = [], len = arguments.length - 2; + while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ]; + + var fnSet; + if (store.has(evt)) { + this.logger('(addToStore)', (evt + " existed")); + fnSet = store.get(evt); + } else { + this.logger('(addToStore)', ("create new Set for " + evt)); + // this is new + fnSet = new Set(); + } + // lazy only store 2 items - this is not the case in V1.6.0 anymore + // we need to check the first parameter is string or not + if (args.length > 2) { + if (Array.isArray(args[0])) { // lazy store + // check if this type of this event already register in the lazy store + var t = args[2]; + if (!this.checkTypeInLazyStore(evt, t)) { + fnSet.add(args); + } + } else { + if (!this.checkContentExist(args, fnSet)) { + this.logger('(addToStore)', "insert new", args); + fnSet.add(args); + } + } + } else { // add straight to lazy store + fnSet.add(args); + } + store.set(evt, fnSet); + return [store, fnSet.size] + }; + + /** + * @param {array} args for compare + * @param {object} fnSet A Set to search from + * @return {boolean} true on exist + */ + NbEventServiceBase.prototype.checkContentExist = function checkContentExist (args, fnSet) { + var list = Array.from(fnSet); + return !!list.filter(function (l) { + var hash = l[0]; + if (hash === args[0]) { + return true; + } + return false; + }).length; + }; + + /** + * get the existing type to make sure no mix type add to the same store + * @param {string} evtName event name + * @param {string} type the type to check + * @return {boolean} true you can add, false then you can't add this type + */ + NbEventServiceBase.prototype.checkTypeInStore = function checkTypeInStore (evtName, type) { + this.validateEvt(evtName, type); + var all = this.$get(evtName, true); + if (all === false) { + // pristine it means you can add + return true; + } + // it should only have ONE type in ONE event store + return !all.filter(function (list) { + var t = list[3]; + return type !== t; + }).length; + }; + + /** + * This is checking just the lazy store because the structure is different + * therefore we need to use a new method to check it + */ + NbEventServiceBase.prototype.checkTypeInLazyStore = function checkTypeInLazyStore (evtName, type) { + this.validateEvt(evtName, type); + var store = this.lazyStore.get(evtName); + this.logger('(checkTypeInLazyStore)', store); + if (store) { + return !!Array + .from(store) + .filter(function (l) { + var t = l[2]; + return t !== type; + }).length + } + return false; + }; + + /** + * wrapper to re-use the addToStore, + * V1.3.0 add extra check to see if this type can add to this evt + * @param {string} evt event name + * @param {string} type on or once + * @param {function} callback function + * @param {object} context the context the function execute in or null + * @return {number} size of the store + */ + NbEventServiceBase.prototype.addToNormalStore = function addToNormalStore (evt, type, callback, context) { + if ( context === void 0 ) context = null; + + this.logger('(addToNormalStore)', evt, type, 'try to add to normal store'); + // @TODO we need to check the existing store for the type first! + if (this.checkTypeInStore(evt, type)) { + this.logger('(addToNormalStore)', (type + " can add to " + evt + " normal store")); + var key = this.hashFnToKey(callback); + var args = [this.normalStore, evt, key, callback, context, type]; + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.normalStore = _store; + return size; + } + return false; + }; + + /** + * Add to lazy store this get calls when the callback is not register yet + * so we only get a payload object or even nothing + * @param {string} evt event name + * @param {array} payload of arguments or empty if there is none + * @param {object} [context=null] the context the callback execute in + * @param {string} [type=false] register a type so no other type can add to this evt + * @return {number} size of the store + */ + NbEventServiceBase.prototype.addToLazyStore = function addToLazyStore (evt, payload, context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + // this is add in V1.6.0 + // when there is type then we will need to check if this already added in lazy store + // and no other type can add to this lazy store + var args = [this.lazyStore, evt, this.toArray(payload), context]; + if (type) { + args.push(type); + } + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.lazyStore = _store; + return size; + }; + + /** + * make sure we store the argument correctly + * @param {*} arg could be array + * @return {array} make sured + */ + NbEventServiceBase.prototype.toArray = function toArray (arg) { + return Array.isArray(arg) ? arg : [arg]; + }; + + /** + * setter to store the Set in private + * @param {object} obj a Set + */ + prototypeAccessors.normalStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj); + }; + + /** + * @return {object} Set object + */ + prototypeAccessors.normalStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_STORE.get(this) + }; + + /** + * setter to store the Set in lazy store + * @param {object} obj a Set + */ + prototypeAccessors.lazyStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj); + }; + + /** + * @return {object} the lazy store Set + */ + prototypeAccessors.lazyStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this) + }; + + /** + * generate a hashKey to identify the function call + * The build-in store some how could store the same values! + * @param {function} fn the converted to string function + * @return {string} hashKey + */ + NbEventServiceBase.prototype.hashFnToKey = function hashFnToKey (fn) { + return hashCode(fn.toString()) + ''; + }; + + Object.defineProperties( NbEventServiceBase.prototype, prototypeAccessors ); + + return NbEventServiceBase; + }(SuspendClass)); + + // The top level + // export + var EventService = /*@__PURE__*/(function (NbStoreService) { + function EventService(config) { + if ( config === void 0 ) config = {}; + + NbStoreService.call(this, config); + } + + if ( NbStoreService ) EventService.__proto__ = NbStoreService; + EventService.prototype = Object.create( NbStoreService && NbStoreService.prototype ); + EventService.prototype.constructor = EventService; + + var prototypeAccessors = { $done: { configurable: true } }; + + /** + * logger function for overwrite + */ + EventService.prototype.logger = function logger () {}; + + ////////////////////////// + // PUBLIC METHODS // + ////////////////////////// + + /** + * Register your evt handler, note we don't check the type here, + * we expect you to be sensible and know what you are doing. + * @param {string} evt name of event + * @param {function} callback bind method --> if it's array or not + * @param {object} [context=null] to execute this call in + * @return {number} the size of the store + */ + EventService.prototype.$on = function $on (evt , callback , context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + var type = 'on'; + this.validate(evt, callback); + // first need to check if this evt is in lazy store + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register first then call later + if (lazyStoreContent === false) { + this.logger('($on)', (evt + " callback is not in lazy store")); + // @TODO we need to check if there was other listener to this + // event and are they the same type then we could solve that + // register the different type to the same event name + + return this.addToNormalStore(evt, type, callback, context) + } + this.logger('($on)', (evt + " found in lazy store")); + // this is when they call $trigger before register this callback + var size = 0; + lazyStoreContent.forEach(function (content) { + var payload = content[0]; + var ctx = content[1]; + var t = content[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + size += this$1.addToNormalStore(evt, type, callback, context || ctx); + }); + return size; + }; + + /** + * once only registered it once, there is no overwrite option here + * @NOTE change in v1.3.0 $once can add multiple listeners + * but once the event fired, it will remove this event (see $only) + * @param {string} evt name + * @param {function} callback to execute + * @param {object} [context=null] the handler execute in + * @return {boolean} result + */ + EventService.prototype.$once = function $once (evt , callback , context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'once'; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (lazyStoreContent === false) { + this.logger('($once)', (evt + " not in the lazy store")); + // v1.3.0 $once now allow to add multiple listeners + return this.addToNormalStore(evt, type, callback, context) + } else { + // now this is the tricky bit + // there is a potential bug here that cause by the developer + // if they call $trigger first, the lazy won't know it's a once call + // so if in the middle they register any call with the same evt name + // then this $once call will be fucked - add this to the documentation + this.logger('($once)', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + }; + + /** + * This one event can only bind one callbackback + * @param {string} evt event name + * @param {function} callback event handler + * @param {object} [context=null] the context the event handler execute in + * @return {boolean} true bind for first time, false already existed + */ + EventService.prototype.$only = function $only (evt, callback, context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'only'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("($only)", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('($only)', (evt + " found data in lazy store to execute")); + var list = Array.from(lazyStoreContent); + // $only allow to trigger this multiple time on the single handler + list.forEach( function (l) { + var payload = l[0]; + var ctx = l[1]; + var t = l[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + }); + } + return added; + }; + + /** + * $only + $once this is because I found a very subtile bug when we pass a + * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0 + * @param {string} evt event name + * @param {function} callback to call later + * @param {object} [context=null] exeucte context + * @return {void} + */ + EventService.prototype.$onlyOnce = function $onlyOnce (evt, callback, context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'onlyOnce'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("($onlyOnce)", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('($onlyOnce)', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== 'onlyOnce') { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + return added; + }; + + /** + * This is a shorthand of $off + $on added in V1.5.0 + * @param {string} evt event name + * @param {function} callback to exeucte + * @param {object} [context = null] or pass a string as type + * @param {string} [type=on] what type of method to replace + * @return {} + */ + EventService.prototype.$replace = function $replace (evt, callback, context, type) { + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = 'on'; + + if (this.validateType(type)) { + this.$off(evt); + var method = this['$' + type]; + return Reflect.apply(method, this, [evt, callback, context]) + } + throw new Error((type + " is not supported!")) + }; + + /** + * trigger the event + * @param {string} evt name NOT allow array anymore! + * @param {mixed} [payload = []] pass to fn + * @param {object|string} [context = null] overwrite what stored + * @param {string} [type=false] if pass this then we need to add type to store too + * @return {number} if it has been execute how many times + */ + EventService.prototype.$trigger = function $trigger (evt , payload , context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + this.validateEvt(evt); + var found = 0; + // first check the normal store + var nStore = this.normalStore; + this.logger('($trigger)', 'normalStore', nStore); + if (nStore.has(evt)) { + // @1.8.0 to add the suspend queue + var added = this.$queue(evt, payload, context, type); + this.logger('($trigger)', evt, 'found; add to queue: ', added); + if (added === true) { + return false; // not executed + } + var nSet = Array.from(nStore.get(evt)); + var ctn = nSet.length; + var hasOnce = false; + for (var i=0; i < ctn; ++i) { + ++found; + // this.logger('found', found) + var ref = nSet[i]; + var _ = ref[0]; + var callback = ref[1]; + var ctx = ref[2]; + var type$1 = ref[3]; + this.run(callback, payload, context || ctx); + if (type$1 === 'once' || type$1 === 'onlyOnce') { + hasOnce = true; + } + } + if (hasOnce) { + nStore.delete(evt); + } + return found; + } + // now this is not register yet + this.addToLazyStore(evt, payload, context, type); + return found; + }; + + /** + * this is an alias to the $trigger + * @NOTE breaking change in V1.6.0 we swap the parameter around + * @param {string} evt event name + * @param {*} params pass to the callback + * @param {string} type of call + * @param {object} context what context callback execute in + * @return {*} from $trigger + */ + EventService.prototype.$call = function $call (evt, params, type, context) { + if ( type === void 0 ) type = false; + if ( context === void 0 ) context = null; + + var args = [evt, params]; + args.push(context, type); + return Reflect.apply(this.$trigger, this, args) + }; + + /** + * remove the evt from all the stores + * @param {string} evt name + * @return {boolean} true actually delete something + */ + EventService.prototype.$off = function $off (evt) { + this.validateEvt(evt); + var stores = [ this.lazyStore, this.normalStore ]; + var found = false; + stores.forEach(function (store) { + if (store.has(evt)) { + found = true; + store.delete(evt); + } + }); + return found; + }; + + /** + * return all the listener from the event + * @param {string} evtName event name + * @param {boolean} [full=false] if true then return the entire content + * @return {array|boolean} listerner(s) or false when not found + */ + EventService.prototype.$get = function $get (evt, full) { + if ( full === void 0 ) full = false; + + this.validateEvt(evt); + var store = this.normalStore; + if (store.has(evt)) { + return Array + .from(store.get(evt)) + .map( function (l) { + if (full) { + return l; + } + var key = l[0]; + var callback = l[1]; + return callback; + }) + } + return false; + }; + + /** + * store the return result from the run + * @param {*} value whatever return from callback + */ + prototypeAccessors.$done.set = function (value) { + this.logger('($done)', 'value: ', value); + if (this.keep) { + this.result.push(value); + } else { + this.result = value; + } + }; + + /** + * @TODO is there any real use with the keep prop? + * getter for $done + * @return {*} whatever last store result + */ + prototypeAccessors.$done.get = function () { + if (this.keep) { + this.logger('(get $done)', this.result); + return this.result[this.result.length - 1] + } + return this.result; + }; + + Object.defineProperties( EventService.prototype, prototypeAccessors ); + + return EventService; + }(NbEventServiceBase)); + + // default + + // this will generate a event emitter and will be use everywhere + // output + function getEventEmitter(debugOn) { + var logger = debugOn ? function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + args.unshift('[NBS]'); + console.log.apply(null, args); + }: undefined; + return new EventService({ logger: logger }) + } + + // this will be the sync version + + /** + * when the client contains a valid contract + * @param {object} config + * @param {object} Fly the fly client + * @return {object} the client + */ + function jsonqlSync(ee, config, Fly) { + var contract = config.contract; + var opts = checkOptions(config); + + var jsonqlBase = new JsonqlBaseClient(opts, Fly); + + return generator(jsonqlBase, opts, contract, ee) + } + + // this one will use the esm module + + /** + * When pass a static contract then it return a static interface + * otherwise it will become the async interface + * @param {object} Fly the http engine + * @param {object} config configuration + * @return {object} jsonqlClient + */ + function jsonqlClient(Fly, config) { + var ee = getEventEmitter(config.debugOn); + if (config.contract && isContract(config.contract)) { + return jsonqlSync(ee, config, Fly) + } + return jsonqlAsync(ee, config, Fly) + } + + // this one will bring the fly.js in + + function full(config) { + if ( config === void 0 ) config = {}; + + return jsonqlClient(Fly$1, config) + } + + return full; + +})); +//# sourceMappingURL=jsonql-client.umd.js.map diff --git a/packages/@jsonql/client/dist/jsonql-client.umd.js.map b/packages/@jsonql/client/dist/jsonql-client.umd.js.map new file mode 100644 index 0000000000000000000000000000000000000000..5096bf5cd43d9157d42ef519257ccf080db55b52 --- /dev/null +++ b/packages/@jsonql/client/dist/jsonql-client.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"jsonql-client.umd.js","sources":["../node_modules/lodash-es/isNull.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/negate.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/error-base.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/log.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-async.js","../node_modules/jsonql-params-validator/src/options/check-options-sync.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/index.js","../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/stores/local-store.js","../src/stores/session-store.js","../src/stores/index.js","../src/utils.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/node_modules/jsonql-utils/src/generic.js","../node_modules/jsonql-jwt/node_modules/jsonql-utils/src/koa.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../src/base/http-cls.js","../src/base/contract-cls.js","../src/base/auth-cls.js","../src/base/base-cls.js","../src/base/index.js","../src/core/methods-generator.js","../src/core/jsonql-api-generator.js","../src/options/base-options.js","../src/options/check-options-async.js","../src/options/check-options.js","../src/jsonql-async.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/suspend.js","../node_modules/nb-event-service/src/store-service.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/ee.js","../src/jsonql-sync.js","../index.js","../full.js"],"sourcesContent":["/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from './lodash'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from './lodash'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from './lodash'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from './lodash'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\n\nimport { isNull, trim, isUndefined } from './lodash'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from './lodash'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from './lodash'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// The base Error of all\nimport whereAmI from './where-am-i'\n\nexport default class JsonqlBaseError extends Error {\n constructor(...args) {\n super(...args)\n }\n\n static where() {\n return whereAmI()\n }\n \n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\nimport JsonqlBaseError from './error-base'\n// when validaton failed\nexport default class JsonqlValidationError extends JsonqlBaseError {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj)\n return !!keys.filter(k => key === k).length;\n}\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail)\n }\n throw new JsonqlError(msg, detail)\n }\n // pass through to the next\n return result;\n}\n","/**\n * just a simple util for helping to debug\n * @param {array} args arguments\n * @return {void}\n */\nexport default function log(...args) {\n try {\n if (window && window.console) {\n Reflect.apply(console.log, console, args)\n }\n } catch(e) {}\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from './lodash'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\nimport log from './log'\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n log(1)\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ))\n case params[0].variable === true: // using spread syntax\n log(2)\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ))\n // with optional defaultValue parameters\n case args.length < params.length:\n log(3)\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ))\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length:\n log(4)\n let ctn = params.length;\n // this happens when we have those array. type\n let _type = [ DEFAULT_TYPE ]\n // we only looking at the first one, this might be a @BUG\n /*\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n } */\n // if we use the params as guide then the rest will get throw out\n // which is not what we want, instead, anything without the param\n // will get a any type and optional flag\n return args.map((arg, i) => {\n let optional = i >= ctn ? true : !!params[i].optional\n let param = params[i] || { type: _type, name: `_${i}` }\n return {\n arg: optional ? getOptionalValue(arg, param) : arg,\n index: i,\n param,\n optional\n }\n })\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n log(5)\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n // v1.4.4 this fixed the problem, the root level optional is from the last fn\n if (p.optional === true || p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from '../lodash'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport log from '../log'\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n log('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n log(ENUM_KEY, value[ENUM_KEY])\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n log(CHECKER_KEY, value[CHECKER_KEY])\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","/// this is port back from the client to share across all projects\nimport { merge } from '../lodash'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:check-options-async')\n\n/**\n * Quick transform\n * @param {object} config that one\n * @param {object} appProps mutation configuration options\n * @return {object} put that arg into the args\n */\nconst configToArgs = (config, appProps) => {\n return Promise.resolve(\n prepareArgsForValidation(config, appProps)\n )\n}\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return configToArgs(config, appProps)\n .then(args1 => {\n // debugFn('args', args1)\n return runValidation(args1, cb)\n })\n // next if every thing good then pass to final merging\n .then(args2 => merge({}, args2, constProps))\n}\n","// this is port back from the client to share across all projects\nimport { merge } from '../lodash'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return merge(\n runValidation(\n prepareArgsForValidation(config, appProps),\n cb\n ),\n constProps\n )\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport { isFunction, isString } from '../lodash'\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants'\n\nimport { checkIsArray } from '../array'\nimport checkIsBoolean from '../boolean'\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n}\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\n// export the two extra functions\nimport isInArray from './src/is-in-array'\nimport isKeyInObjectFn from './src/is-key-in-object'\n\nexport const inArray = isInArray;\nexport const isKeyInObject = isKeyInObjectFn;\n","module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// bunch of generic helpers\nimport debug from 'debug'\nimport { isArray, isPlainObject, trim } from 'lodash-es'\n\n/**\n * @param {string} name the name part after the :\n * @param {string} baseName the base before the :\n */\nexport const getDebug = (name, baseName = 'jsonql') => {\n return debug(baseName).extend(name)\n}\n\n/**\n * DIY in Array\n * @param {array} arr to check from\n * @param {*} value to check against\n * @return {boolean} true on found\n */\nexport const inArray = (arr, value) => !!arr.filter(a => a === value).length;\n\n// quick and dirty to turn non array to array\nexport const toArray = (arg) => isArray(arg) ? arg : [arg];\n\n/**\n * @param {object} obj for search\n * @param {string} key target\n * @return {boolean} true on success\n */\nexport const isKeyInObject = function(obj, key) {\n const keys = Object.keys(obj)\n return inArray(keys, key)\n}\n\n/**\n * create a event name\n * @param {string[]} args\n * @return {string} event name for use\n */\nexport const createEvt = (...args) => args.join('_')\n\n/**\n * @param {boolean} sec return in second or not\n * @return {number} timestamp\n */\nexport const timestamp = (sec = false) => {\n let time = Date.now()\n return sec ? Math.floor( time / 1000 ) : time;\n}\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * construct a url with cache burster\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\n/**\n * @return {object} _cb as key with timestamp\n */\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * From underscore.string library\n * @BUG there is a bug here with the non-standard name start with _\n * @param {string} str string\n * @return {string} dasherize string\n */\nexport const dasherize = str => (\n trim(str)\n .replace(/([A-Z])/g, '-$1')\n .replace(/[-_\\s]+/g, '-')\n .toLowerCase()\n)\n\n/**\n * simple util method to get the value\n * @param {string} name of the key\n * @param {object} obj to take value from\n * @return {*} the object value id by name or undefined\n */\nexport const getConfigValue = (name, obj) => (\n obj && isPlainObject(obj) ? ( (name in obj) ? obj[name] : undefined ) : undefined\n)\n\n/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nexport const isNotEmpty = function(param) {\n return param !== undefined && param !== false && param !== null && trim(param) !== '';\n}\n","// koa specific methods\nimport {\n CONTENT_TYPE,\n SUCCESS_STATUS,\n FORBIDDEN_STATUS\n} from 'jsonql-constants'\n// fix the default is not export by module error\nimport * as jsonqlErrors from 'jsonql-errors'\nimport {\n getDocLen,\n headerParser,\n isHeaderPresent,\n getCallMethod,\n getPathToFn,\n packResult,\n packError\n} from './middleware'\nimport { dasherize, getDebug } from './generic'\nconst debug = getDebug(`koa`, `jsonql-utils`)\n/**\n * @TODO need to be more flexible\n * @param {object} ctx koa\n * @param {object} opts configuration\n * @return {boolean} if it match\n */\nexport const isJsonqlPath = (ctx, opts) => ctx.path === opts.jsonqlPath;\n\n/**\n * combine two check in one and save time\n * @param {object} ctx koa\n * @param {object} opts config\n * @return {boolean} check result\n */\nexport const isJsonqlRequest = (ctx, opts) => {\n const header = isHeaderPresent(ctx.request, opts.contentType)\n if (header) {\n return isJsonqlPath(ctx, opts)\n }\n return false;\n}\n\n/**\n * check if this is point to the jsonql console\n * @param {object} ctx koa context\n * @param {object} opts config\n * @return {boolean}\n */\nexport const isJsonqlConsoleUrl = (ctx, opts) => (\n ctx.method === 'GET' && isJsonqlPath(ctx, opts)\n)\n\n/**\n * Handle the output\n * @param {object} opts configuration\n * @return {function} with ctx and body as params\n */\nexport const handleOutput = function(opts) {\n return function(ctx, body) {\n ctx.size = getDocLen(body)\n ctx.type = opts.contentType;\n ctx.status = SUCCESS_STATUS;\n ctx.body = body;\n }\n}\n\n/**\n * handle HTML output for the web console\n * @param {object} ctx koa context\n * @param {string} body output content\n * @return {void}\n */\nexport const handleHtmlOutput = function(ctx, body) {\n ctx.size = getDocLen(body)\n ctx.type = 'text/html';\n ctx.status = SUCCESS_STATUS;\n ctx.body = body + ''; // just make sure its string output\n}\n\n/**\n * use the ctx to generate error output\n * V1.1.0 we render this as a normal output with status 200\n * then on the client side will check against the result object for error\n * @param {object} ctx context\n * @param {number} code 404 / 500 etc\n * @param {object} e actual error\n * @param {string} message if there is one\n * @param {string} name custom error class name\n */\nexport const ctxErrorHandler = function(ctx, code, e, message = '') {\n const render = handleOutput({contentType: CONTENT_TYPE})\n debug('[ctxErrorHandler]', code, e, message)\n let name;\n if (typeof code === 'string') {\n name = code;\n code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1;\n } else {\n debug(`[ctxErrorHandler] using getErrorByStatus`)\n name = jsonqlErrors.getErrorByStatus(code)\n }\n debug(`[ctxErrorHandler.name]`, name)\n // preserve the message\n if (!message && e && e.message) {\n message = e.message;\n }\n return render(ctx, packError(e, name, code, message))\n}\n\n/**\n * Just a wrapper to be clearer what error is it\n * @param {object} ctx koa\n * @param {object} e error\n * @return {undefined} nothing\n */\nexport const forbiddenHandler = (ctx, e) => (\n ctxErrorHandler(ctx, FORBIDDEN_STATUS, e, 'JsonqlAuthorisationError')\n)\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\nimport { timestamp } from 'jsonql-utils'\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || timestamp()\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// base HttpClass\nimport merge from 'lodash-es/merge'\nimport {\n createQuery,\n createMutation,\n getNameFromPayload,\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n isObject,\n isString\n} from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME,\n SHOW_CONTRACT_DESC_PARAM\n} from 'jsonql-constants'\n\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nconst _log = (...args) => {\n try {\n if (window && window.console) {\n Reflect.apply(console.log, null, args)\n }\n } catch(e) {}\n}\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n // change the way how we init Fly\n // flyio now become external depedencies and it makes it easier to switch\n // @BUG should we run test to check if we have the windows object?\n _log(opts)\n this.fly = opts.Fly ? new opts.Fly() : new Fly()\n // to a different environment like WeChat mini app\n this.opts = opts;\n this.extraHeader = {};\n // @1.2.1 for adding query to the call on the fly\n this.extraParams = {};\n // this.log('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = merge({}, cacheBurst(), this.extraParams)\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, { method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n const headers = this.getHeaders();\n this.log('request interceptor call', headers)\n\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n this.log('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n this.extraParams = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n if (this.opts.showContractDesc) {\n this.extraParams = merge({}, this.extraParams, SHOW_CONTRACT_DESC_PARAM)\n }\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n this.log('get contract result', result)\n // when refresh the window the result is different!\n // @TODO need to check the Koa side about why is that\n // also it should set a flag if we want the description or not\n if (result.cache && result.contract) {\n return result.contract;\n }\n // just the normal result\n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport { timestamp, isContract, ENDPOINT_TABLE } from '../utils'\nimport { localStore } from '../stores'\n\nimport HttpClass from './http-cls';\n\n// export\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contracts = this.readContract()\n this.log('getContract first call', contracts)\n if (contracts && Array.isArray(contracts)) {\n const contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]\n if (contract) {\n return Promise.resolve(contract)\n }\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isContract(contract)) {\n throw new JsonqlValidationError(`Contract is malformed!`)\n //return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired)\n if (!isNaN(expired) && expired > 0) {\n args.push(expired)\n }\n }\n // calling the setter\n this.jsonqlContract = args;\n // return it\n this.log('storeContract return result', contract)\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts)\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport { localStore, sessionStore } from '../stores'\nimport { timestamp, inArray, ENDPOINT_TABLE, USERDATA_TABLE } from '../utils'\n\nimport AuthCls from './auth-cls'\n\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts, Fly = null) {\n if (Fly) {\n opts.Fly = Fly;\n }\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n console.info('storeIt', args)\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey;\n let _args = [ key ]\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n _args.push(contracts)\n if (expired) {\n _args.push(expired)\n }\n if (this.opts.keepContract) {\n this.storeIt = _args;\n }\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n\n /**\n * this one will use the sessionStore\n * basically we hook this onto the token store and decode it to store here\n */\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n /**\n * This also manage the index internally\n * There is NO need to store them in an array\n * because each instance contain one end point\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n\n /**\n * this one store in the session store\n * get login userdata decoded jwt\n * @return {object|null}\n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n /**\n * simple log\n */\n log(...args) {\n if (this.opts.debugOn === true) {\n Reflect.apply(console.info, console, args)\n }\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","// breaking out the inner methods generator in here\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * Here just generate the methods calls\n * @param {object} jsonqlInstance what it said\n * @param {object} ee event emitter\n * @param {object} config configuration\n * @param {object} contract the map\n * @return {object} with mapped methods\n */\nexport default function methodsGenerator(jsonqlInstance, ee, config, contract) {\n let obj = {query: {}, mutation: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n obj.auth = {} // v1.3.1 add back the auth prop name\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj.auth[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.$trigger(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj.auth[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.$trigger(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj.auth[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.$trigger(LOGOUT_NAME, KEY_WORD)\n }\n }\n }\n return obj;\n}\n","// Generate the resolver for developer to use\n\n// @TODO when enableAuth we need to add one extra check\n// before the resolver call make it to the core\n// which is checking the login state, if the developer\n// is calling a private method without logging in\n// then we should throw the JsonqlForbiddenError at this point\n// instead of making a round trip to the server\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\n\nimport methodsGenerator from './methods-generator'\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contract the contract\n * @param {object} ee eventEmitter\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contract, ee) => {\n // V1.3.0 - now everything wrap inside this method\n let obj = methodsGenerator(jsonqlInstance, ee, config, contract)\n // create the rest of the methods\n if (config.enableAuth) {\n /**\n * new method to allow retrieve the current login user data\n * @return {*} userdata\n */\n obj.userdata = () => jsonqlInstance.userdata;\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n // obj.eventEmitter = ee;\n // this will require a param\n if (config.exposeContract) {\n obj.getContract = () => jsonqlInstance.get()\n }\n // this is for the ws to use later\n obj.eventEmitter = ee;\n obj.version = '__VERSION__';\n // output\n return obj;\n};\n\nexport default generator;\n","// all the client configuration options here\nimport {\n JSONQL_PATH,\n CONTENT_TYPE,\n BEARER,\n CLIENT_STORAGE_KEY,\n CLIENT_AUTH_KEY,\n CONTRACT_KEY_NAME,\n AUTH_HEADER,\n ISSUER_NAME,\n LOGOUT_NAME,\n BOOLEAN_TYPE,\n STRING_TYPE,\n NUMBER_TYPE,\n DEFAULT_HEADER\n} from 'jsonql-constants'\nimport { createConfig } from 'jsonql-params-validator'\nexport const constProps = {\n contract: false,\n MUTATION_ARGS: ['name', 'payload', 'conditions'], // this seems wrong?\n CONTENT_TYPE,\n BEARER,\n AUTH_HEADER\n}\n\n// grab the localhost name and put into the hostname as default\nconst getHostName = () => (\n [window.location.protocol, window.location.host].join('//')\n)\n\nexport const appProps = {\n\n hostname: createConfig(getHostName(), [STRING_TYPE]), // required the hostname\n jsonqlPath: createConfig(JSONQL_PATH, [STRING_TYPE]), // The path on the server\n\n loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]),\n logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]),\n // add to koa v1.3.0 - this might remove in the future\n enableJsonp: createConfig(false, [BOOLEAN_TYPE]),\n enableAuth: createConfig(false, [BOOLEAN_TYPE]),\n // enable useJwt by default\n useJwt: createConfig(true, [BOOLEAN_TYPE]),\n\n // the header\n // v1.2.0 we are using this option during the dev\n // so it won't save anything to the localstorage and fetch a new contract\n // whenever the browser reload\n useLocalstorage: createConfig(true, [BOOLEAN_TYPE]), // should we store the contract into localStorage\n storageKey: createConfig(CLIENT_STORAGE_KEY, [STRING_TYPE]),// the key to use when store into localStorage\n authKey: createConfig(CLIENT_AUTH_KEY, [STRING_TYPE]),// the key to use when store into the sessionStorage\n contractExpired: createConfig(0, [NUMBER_TYPE]),// -1 always fetch contract,\n // 0 never expired,\n // > 0 then compare the timestamp with the current one to see if we need to get contract again\n // useful during development\n keepContract: createConfig(true, [BOOLEAN_TYPE]),\n exposeContract: createConfig(false, [BOOLEAN_TYPE]),\n // @1.2.1 new option for the contract-console to fetch the contract with description\n showContractDesc: createConfig(false, [BOOLEAN_TYPE]),\n contractKey: createConfig(false, [BOOLEAN_TYPE]), // if the server side is lock by the key you need this\n contractKeyName: createConfig(CONTRACT_KEY_NAME, [STRING_TYPE]), // same as above they go in pairs\n enableTimeout: createConfig(false, [BOOLEAN_TYPE]), // @TODO\n timeout: createConfig(5000, [NUMBER_TYPE]), // 5 seconds\n returnInstance: createConfig(false, [BOOLEAN_TYPE]),\n allowReturnRawToken: createConfig(false, [BOOLEAN_TYPE]),\n debugOn: createConfig(false, [BOOLEAN_TYPE])\n}\n","// we must ensure the user passing the correct options\n// therefore we need to validate against the properties as well\n\nimport { appProps, constProps } from './base-options'\nimport { checkConfigAsync } from 'jsonql-params-validator'\n\nexport default function checkOptionsAsync(config) {\n let { contract } = config;\n return checkConfigAsync(config, appProps, constProps)\n .then(opts => {\n opts.contract = contract;\n return opts;\n })\n}\n","// This is for the sync version therefore we don't need to care about the contract options\nimport { appProps, constProps } from './base-options'\nimport { checkConfig } from 'jsonql-params-validator'\n\nexport default function checkOptions(config) {\n return checkConfig(config, appProps, constProps)\n}\n","// this is new for the flyio and normalize the name from now on\nimport JsonqlBaseClient from './base'\nimport generator from './core/jsonql-api-generator'\nimport { checkOptionsAsync } from './options'\nimport { getContractFromConfig } from './utils'\n\n/**\n * Main interface for jsonql fetch api\n * @param {object} config\n * @param {object} Fly this is really pain in the backside ... long story\n * @return {object} jsonql client\n */\nexport default function(ee, config = {}, Fly = null) {\n return checkOptionsAsync(config)\n .then(opts => (\n {\n baseClient: new JsonqlBaseClient(opts, Fly),\n opts: opts\n }\n ))\n .then( ({baseClient, opts}) => (\n getContractFromConfig(baseClient, opts.contract)\n .then(contract => generator(baseClient, opts, contract, ee)\n )\n )\n )\n}\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// making all the functionality on it's own\n// import { WatchClass } from './watch'\n\nexport default class SuspendClass {\n\n constructor() {\n // suspend, release and queue\n this.__suspend__ = null;\n this.queueStore = new Set()\n /*\n this.watch('suspend', function(value, prop, oldValue) {\n this.logger(`${prop} set from ${oldValue} to ${value}`)\n // it means it set the suspend = true then release it\n if (oldValue === true && value === false) {\n // we want this happen after the return happens\n setTimeout(() => {\n this.release()\n }, 1)\n }\n return value; // we need to return the value to store it\n })\n */\n }\n\n /**\n * setter to set the suspend and check if it's boolean value\n * @param {boolean} value to trigger\n */\n set $suspend(value) {\n if (typeof value === 'boolean') {\n const lastValue = this.__suspend__;\n this.__suspend__ = value;\n this.logger('($suspend)', `Change from ${lastValue} --> ${value}`)\n if (lastValue === true && value === false) {\n setTimeout(() => {\n this.release()\n }, 1)\n }\n } else {\n throw new Error(`$suspend only accept Boolean value!`)\n }\n }\n\n /**\n * queuing call up when it's in suspend mode\n * @param {any} value\n * @return {Boolean} true when added or false when it's not\n */\n $queue(...args) {\n if (this.__suspend__ === true) {\n this.logger('($queue)', 'added to $queue', args)\n // there shouldn't be any duplicate ...\n this.queueStore.add(args)\n }\n return this.__suspend__;\n }\n\n /**\n * a getter to get all the store queue\n * @return {array} Set turn into Array before return\n */\n get $queues() {\n let size = this.queueStore.size;\n this.logger('($queues)', `size: ${size}`)\n if (size > 0) {\n return Array.from(this.queueStore)\n }\n return []\n }\n\n /**\n * Release the queue\n * @return {int} size if any\n */\n release() {\n let size = this.queueStore.size\n this.logger('(release)', `Release was called ${size}`)\n if (size > 0) {\n const queue = Array.from(this.queueStore)\n this.queueStore.clear()\n this.logger('queue', queue)\n queue.forEach(args => {\n this.logger(args)\n Reflect.apply(this.$trigger, this, args)\n })\n this.logger(`Release size ${this.queueStore.size}`)\n }\n }\n}\n","// break up the main file because its getting way too long\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code'\nimport SuspendClass from './suspend'\n\nexport default class NbEventServiceBase extends SuspendClass {\n\n constructor(config = {}) {\n super()\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * validate the event name(s)\n * @param {string[]} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(...evt) {\n evt.forEach(e => {\n if (typeof e !== 'string') {\n this.logger('(validateEvt)', e)\n throw new Error(`event name must be string type!`)\n }\n })\n return true;\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('(run)', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('(takeFromStore)', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('(takeFromStore)', `has ${evt}`, content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('(addToStore)', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('(addToStore)', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('(addToStore)', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName, type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName, type)\n let store = this.lazyStore.get(evtName)\n this.logger('(checkTypeInLazyStore)', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('(addToNormalStore)', evt, type, 'try to add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger('(addToNormalStore)', `${type} can add to ${evt} normal store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n}\n","// The top level\nimport NbStoreService from './store-service'\n// export\nexport default class EventService extends NbStoreService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n super(config)\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('($on)', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('($on)', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('($once)', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('($once)', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`($only)`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('($only)', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`($onlyOnce)`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('($onlyOnce)', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('($trigger)', 'normalStore', nStore)\n if (nStore.has(evt)) {\n // @1.8.0 to add the suspend queue\n let added = this.$queue(evt, payload, context, type)\n this.logger('($trigger)', evt, 'found; add to queue: ', added)\n if (added === true) {\n return false; // not executed\n }\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('($done)', 'value: ', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger('(get $done)', this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n// output\nexport default function(debugOn) {\n let logger = debugOn ? (...args) => {\n args.unshift('[NBS]')\n console.log.apply(null, args)\n }: undefined;\n return new NBEventService({ logger })\n}\n","// this will be the sync version\nimport JsonqlBaseClient from './base'\nimport generator from './core/jsonql-api-generator'\nimport { checkOptions } from './options'\nimport ee from './ee'\n\n/**\n * when the client contains a valid contract\n * @param {object} config\n * @param {object} Fly the fly client\n * @return {object} the client\n */\nexport default function jsonqlSync(ee, config, Fly) {\n const { contract } = config;\n const opts = checkOptions(config)\n\n const jsonqlBase = new JsonqlBaseClient(opts, Fly)\n\n return generator(jsonqlBase, opts, contract, ee)\n}\n","// this one will use the esm module\n\n// main export interface\n\n// @2019-05-09 new interface export with Fetch\nimport { jsonqlAsync, jsonqlSync, ee as getEventEmitter } from './src'\nimport { isContract } from './src/utils'\n\n/**\n * When pass a static contract then it return a static interface\n * otherwise it will become the async interface\n * @param {object} Fly the http engine\n * @param {object} config configuration\n * @return {object} jsonqlClient\n */\nexport default function jsonqlClient(Fly, config) {\n const ee = getEventEmitter(config.debugOn)\n if (config.contract && isContract(config.contract)) {\n return jsonqlSync(ee, config, Fly)\n }\n return jsonqlAsync(ee, config, Fly)\n}\n","// this one will bring the fly.js in\n// also the built jsonql-client.umd.js together\n// init it @TODO placeholder this Fly import and switch using the NODE_ENV\n// because we are going to create one for wechat and one for node\n\nimport Fly from 'flyio/dist/npm/fly'\nimport jsonqlClient from './index'\n\nexport default function(config = {}) {\n return jsonqlClient(Fly, config)\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;;ACAA;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/packages/@jsonql/client/full.js b/packages/@jsonql/client/full.js new file mode 100644 index 0000000000000000000000000000000000000000..f57970e40423682f01a64d14e37d7cd7aaedc093 --- /dev/null +++ b/packages/@jsonql/client/full.js @@ -0,0 +1,11 @@ +// this one will bring the fly.js in +// also the built jsonql-client.umd.js together +// init it @TODO placeholder this Fly import and switch using the NODE_ENV +// because we are going to create one for wechat and one for node + +import Fly from 'flyio/dist/npm/fly' +import jsonqlClient from './index' + +export default function(config = {}) { + return jsonqlClient(Fly, config) +} diff --git a/packages/@jsonql/client/index.js b/packages/@jsonql/client/index.js new file mode 100644 index 0000000000000000000000000000000000000000..877f2d1e5f074a6ef4d700da3d7565edf90015d9 --- /dev/null +++ b/packages/@jsonql/client/index.js @@ -0,0 +1,22 @@ +// this one will use the esm module + +// main export interface + +// @2019-05-09 new interface export with Fetch +import { jsonqlAsync, jsonqlSync, ee as getEventEmitter } from './src' +import { isContract } from './src/utils' + +/** + * When pass a static contract then it return a static interface + * otherwise it will become the async interface + * @param {object} Fly the http engine + * @param {object} config configuration + * @return {object} jsonqlClient + */ +export default function jsonqlClient(Fly, config) { + const ee = getEventEmitter(config.debugOn) + if (config.contract && isContract(config.contract)) { + return jsonqlSync(ee, config, Fly) + } + return jsonqlAsync(ee, config, Fly) +} diff --git a/packages/@jsonql/client/package.json b/packages/@jsonql/client/package.json index 5181901a1a68a95b58059d8aab014a7b2bcbe8b2..a7a5b0e49e6555e129d7bb74a259a788e18920a4 100644 --- a/packages/@jsonql/client/package.json +++ b/packages/@jsonql/client/package.json @@ -1,25 +1,32 @@ { "name": "@jsonql/client", - "version": "0.0.1", - "description": "jsonql combine client for http / ws develop with Typescript", - "main": "index.js", - "module": "src/index.ts", - "browser": "dist/jsonql-client.js", + "version": "0.1.0", + "description": "jsonql js http client for browser", + "main": "dist/jsonql-client.umd.js", + "module": "index.js", + "browser": "dist/jsonql-client.umd.js", + "files": [ + "src", + "dist", + "index.js", + "static.js" + ], "scripts": { - "test": "npm run build && DEBUG=jsonql* node ./tests/browser/run-qunit.js", + "test": "npm run build && npm run test:browser", "prepare": "npm run build", + "test:utils": "node ./main.js", "test:node": "DEBUG=jsonql* ava --verbose", "test:contract": "DEBUG=jsonql-* ava ./tests/contract-lock.test.js", - "test:browser": "npm run build && npm run run:browser", + "test:browser": "DEBUG=jsonql* node ./tests/qunit/run-qunit.js", "test:fn": "ava ./tests/fn.test.js", "run:browser": "DEBUG=jsonql-* node ./tests/fixtures/run.js", "start": "rollup -c -w --environment NODE_ENV:dev", - "build": "npm run build:production && npm run build:oop", + "build": "npm run build:umd && npm run build:browser && npm run build:static && npm run build:full", "build:umd": "rollup -c", - "build:production": "NODE_ENV=production rollup -c", - "build:test": "rollup -c -w", - "build:oop": "rollup --config ./rollup.oop.config.js", - "build:stores": "NODE_ENV=stores rollup --config ./rollup.oop.config.js", + "build:browser": "NODE_ENV=BROWSER rollup -c", + "build:static": "NODE_ENV=STATIC rollup -c", + "build:full": "NODE_ENV=FULL rollup -c", + "_build:stores": "NODE_ENV=stores rollup --config ./rollup.test.config.js", "contract:file": "node ./tests/fixtures/contract.js", "contract": "npm run contract:base && npm run contract:public", "contract:base": "DEBUG=jsonql-contract* node ../contract-cli/cmd.js ./tests/fixtures/resolvers ./tests/fixtures/contracts/tmp", @@ -27,15 +34,13 @@ "qunit": "npm run build:umd && DEBUG=jsonql-*,server-io-core* node ./tests/qunit/run-qunit.js" }, "keywords": [ + "jsonql", + "client", + "browser", "json", "ql", "js" ], - "files": [ - "lib", - "src", - "index.js" - ], "author": "Joel Chu ", "homepage": "jsonql.org", "repository": { @@ -45,41 +50,41 @@ "license": "MIT", "dependencies": { "flyio": "^0.6.14", - "jsonql-constants": "^1.7.6", - "jsonql-errors": "^1.0.9", - "jsonql-jwt": "^1.2.1", - "jsonql-params-validator": "^1.4.3", - "lodash-es": "^4.17.11", - "nb-event-service": "^1.6.0", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", + "jsonql-jwt": "^1.3.1", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.6.8", + "lodash-es": "^4.17.15", + "nb-event-service": "^1.8.3", "store": "^2.0.12" }, "devDependencies": { - "ava": "^2.1.0", + "@jsonql/koa": "^0.2.5", + "ava": "^2.4.0", "browser-env": "^3.2.6", "debug": "^4.1.1", "esm": "^3.2.25", "glob": "^7.1.4", - "jsonql-koa": "^1.2.4", "koa-favicon": "^2.0.1", "nyc": "^14.1.1", "promise-polyfill": "8.1.3", "qunit": "^2.9.2", - "rollup": "^1.16.3", - "rollup-plugin-alias": "^1.5.2", - "rollup-plugin-analyzer": "^3.0.1", + "rollup": "^1.21.4", + "rollup-plugin-alias": "^2.0.0", + "rollup-plugin-analyzer": "^3.2.1", "rollup-plugin-async": "^1.2.0", - "rollup-plugin-buble": "^0.19.6", + "rollup-plugin-buble": "^0.19.8", "rollup-plugin-bundle-size": "^1.0.3", - "rollup-plugin-commonjs": "^10.0.1", - "rollup-plugin-copy": "^3.0.0", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-copy": "^3.1.0", "rollup-plugin-node-builtins": "^2.1.2", "rollup-plugin-node-globals": "^1.4.0", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^5.0.0", - "rollup-plugin-uglify": "^6.0.2", - "server-io-core": "^1.1.0", + "rollup-plugin-terser": "^5.1.2", + "server-io-core": "^1.2.0", "window": "^4.2.6" }, "ava": { @@ -89,9 +94,6 @@ "!tests/browser/*.*", "!tests/qunit/*.*" ], - "require": [ - "./tests/fixtures/helpers/setup-browser.js" - ], "cache": false, "concurrency": 5, "failFast": true, diff --git a/packages/@jsonql/client/rollup.config.js b/packages/@jsonql/client/rollup.config.js new file mode 100644 index 0000000000000000000000000000000000000000..80a4e91f360fb44f65c09229dbf2915265ba8060 --- /dev/null +++ b/packages/@jsonql/client/rollup.config.js @@ -0,0 +1,95 @@ +/** + * Rollup config for building the slim version + */ +import { join } from 'path' +import buble from 'rollup-plugin-buble' +import { terser } from "rollup-plugin-terser" +import replace from 'rollup-plugin-replace' +import commonjs from 'rollup-plugin-commonjs' +import nodeResolve from 'rollup-plugin-node-resolve' +import nodeGlobals from 'rollup-plugin-node-globals' +import builtins from 'rollup-plugin-node-builtins' +import size from 'rollup-plugin-bundle-size' +import async from 'rollup-plugin-async' + +import pkg from './package.json' + +const env = process.env.NODE_ENV; + +let plugins = [ + buble({ + objectAssign: 'Object.assign' + }), + nodeResolve({ + preferBuiltins: true, + mainFields: ['module', 'browser'] + }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + builtins(), + async(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + '__VERSION__': pkg.version + }) +] + + + +let globals = { + 'debug': 'debug', + 'promise-polyfill': 'Promise', + 'flyio': 'Fly' +} +let external = [ + 'flyio', + 'debug', + 'fetch', + 'Promise', + 'promise-polyfill', + 'superagent', + 'handlebars', + 'tty' +] +let moduleName = 'jsonqlClient' +let sourceFile = 'index.js' +let distFile = 'core.js' +switch (env) { + case 'BROWSER': + sourceFile = 'full.js' + distFile = join('dist', 'jsonql-client.umd.js') + break; + case 'STATIC': + moduleName = 'jsonqlClientStatic' + sourceFile = join('src', 'static.js') + distFile = 'static.js' + plugins.push(terser()) + break; + case 'FULL': + moduleName = 'jsonqlClientStatic' + sourceFile = join('src', 'static-full.js') + distFile = join('dist', 'jsonql-client.static.js') + break; + default: + sourceFile = 'index.js' + plugins.push(terser()) +} + +plugins.push(size()) + +let config = { + input: join(__dirname, sourceFile), + output: { + name: moduleName, + file: join(__dirname, distFile), + format: 'umd', + sourcemap: true, + globals + }, + plugins, + external +} + +export default config diff --git a/packages/@jsonql/client/src/base/auth-cls.js b/packages/@jsonql/client/src/base/auth-cls.js new file mode 100644 index 0000000000000000000000000000000000000000..7b470f6d193eca7ca553128cd1efd2ce1ba3325a --- /dev/null +++ b/packages/@jsonql/client/src/base/auth-cls.js @@ -0,0 +1,76 @@ +// this is the new auth class that integrate with the jsonql-jwt +// all the auth related methods will be here +import { decodeToken } from 'jsonql-jwt' +import { + CREDENTIAL_STORAGE_KEY, + AUTH_HEADER, + BEARER +} from 'jsonql-constants' +// chain +import ContractClass from './contract-cls' +// export +export default class AuthClass extends ContractClass { + + constructor(opts) { + super(opts) + if (opts.enableAuth && opts.useJwt) { + this.setDecoder = decodeToken; + } + } + + /** + * Getter to get the login userdata + * @return {mixed} userdata + */ + get userdata() { + return this.jsonqlUserdata; // see base-cls + } + + /** + * Return the token from session store + * @return {string} token + */ + get rawAuthToken() { + // this should return from the base + return this.jsonqlToken; // see base-cls + } + + /** + * Setter to add a decoder when retrieve user token + * @param {function} d a decoder + */ + set setDecoder(d) { + if (typeof d === 'function') { + this.decoder = d; + } + } + + /** + * Setter after login success + * @TODO this move to a new class to handle multiple login + * @param {string} token to store + * @return {*} success store + */ + storeToken(token) { + return this.jsonqlToken = token; + } + + /** + * for overwrite + * @param {string} token stored token + * @return {string} token + */ + decoder(token) { + return token; + } + + /** + * Construct the auth header + * @return {object} header + */ + getAuthHeader() { + const token = this.rawAuthToken; + return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {}; + } + +} diff --git a/packages/@jsonql/client/src/base/base-cls.js b/packages/@jsonql/client/src/base/base-cls.js new file mode 100644 index 0000000000000000000000000000000000000000..3a45221058530d3d5dfe26c2de4e261adca4dcaf --- /dev/null +++ b/packages/@jsonql/client/src/base/base-cls.js @@ -0,0 +1,164 @@ +// this the core of the internal storage management +import { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants' +import { isObject, isArray } from 'jsonql-params-validator' +import { JsonqlValidationError } from 'jsonql-errors' +// chaining into the classes +import { localStore, sessionStore } from '../stores' +import { timestamp, inArray, ENDPOINT_TABLE, USERDATA_TABLE } from '../utils' + +import AuthCls from './auth-cls' + +// This class will only focus on the storage system +export default class JsonqlBaseClient extends AuthCls { + + constructor(opts, Fly = null) { + if (Fly) { + opts.Fly = Fly; + } + super(opts) + } + + // @TODO + set storeIt(args) { + console.info('storeIt', args) + // the args MUST contain [0] the key , [1] the content [2] optional expired in + if (isArray(args) && args.length >= 2) { + Reflect.apply(localStore.set, localStore, args) + } + throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`) + } + + // this table index key will drive the contract + // also it should not allow to change dynamicly + // because this is how different client can id itself + // OK this could be self manage because when init a new client + // it will add a new endpoint and we will know if they are the same or not + // but the check here + set jsonqlEndpoint(endpoint) { + let urls = localStore.get(ENDPOINT_TABLE) || [] + // should check if this url already existed? + if (!inArray(urls, endpoint)) { + urls.push(endpoint) + this.storeId = [ENDPOINT_TABLE, urls] + this[ENDPOINT_TABLE + 'Index'] = urls.length - 1; + } + } + + // by the time it call the save contract already been checked + set jsonqlContract(args) { + const key = this.opts.storageKey; + let _args = [ key ] + let [ contract, expired ] = args; + // get the endpoint index + let contracts = localStore.get(key) || [] + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + _args.push(contracts) + if (expired) { + _args.push(expired) + } + if (this.opts.keepContract) { + this.storeIt = _args; + } + } + + /** + * save token + * @param {string} token to store + * @return {string|boolean} false on failed + */ + set jsonqlToken(token) { + const key = CREDENTIAL_STORAGE_KEY; + let tokens = localStorage.get(key) || [] + if (!inArray(tokens, token)) { + let index = tokens.length - 1; + tokens[ index ] = token; + this[key + 'Index'] = index; + let args = [key, tokens] + if (this.opts.tokenExpired) { + const expired = parseFloat(this.opts.tokenExpired) + if (!isNaN(expired) && expired > 0) { + const ts = timestamp() + args.push( ts + parseFloat(expired) ) + } + } + this.storeIt = args; + // now decode it and store in the userdata + this.jsonqlUserdata = this.decoder(token) + return token; + } + return false; + } + + /** + * this one will use the sessionStore + * basically we hook this onto the token store and decode it to store here + */ + set jsonqlUserdata(userdata) { + const args = [USERDATA_TABLE, userdata] + if (userdata.exp) { + args.push(userdata.exp) + } + return Reflect.apply(localStore.set, localStore, args) + } + + /** + * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point + * @return {string} the end point to call + */ + get jsonqlEndpoint() { + let urls = localStore.get(ENDPOINT_TABLE) + if (!urls) { + const { hostname, jsonqlPath } = this.opts; + let url = [hostname, jsonqlPath].join('/') + this.jsonqlEndpoint = url; + return url; + } + return urls[this[ENDPOINT_TABLE + 'Index']] + } + + /** + * If already stored then return it by the end point index + * or false when there is none + * 1.2.0 start using the keepContract option (replace the useLocalStorage) + * @return {object|boolean} as described above + */ + get jsonqlContract() { + const key = this.opts.storageKey + let contracts = localStore.get(key) || [] + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false + } + + /** + * Jsonql token getter + * @return {string|boolean} false when failed + */ + get jsonqlToken() { + const key = CREDENTIAL_STORAGE_KEY; + let tokens = localStorage.get(key) + if (tokens) { + return tokens[ this[key + 'Index'] ] + } + return false; + } + + /** + * this one store in the session store + * get login userdata decoded jwt + * @return {object|null} + */ + get jsonqlUserdata() { + return sessionStore.get(USERDATA_TABLE) + } + + /** + * simple log + */ + log(...args) { + if (this.opts.debugOn === true) { + Reflect.apply(console.info, console, args) + } + } + +} diff --git a/packages/@jsonql/client/src/base/contract-cls.js b/packages/@jsonql/client/src/base/contract-cls.js new file mode 100644 index 0000000000000000000000000000000000000000..aec10a4411c82be005591200e5620ca03bf754dd --- /dev/null +++ b/packages/@jsonql/client/src/base/contract-cls.js @@ -0,0 +1,79 @@ +// all the contract related methods will be here +import { JsonqlValidationError } from 'jsonql-errors' + +import { timestamp, isContract, ENDPOINT_TABLE } from '../utils' +import { localStore } from '../stores' + +import HttpClass from './http-cls'; + +// export +export default class ContractClass extends HttpClass { + + constructor(opts) { + super(opts) + } + + /** + * return the contract public api + * @return {object} contract + */ + getContract() { + const contracts = this.readContract() + this.log('getContract first call', contracts) + if (contracts && Array.isArray(contracts)) { + const contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] + if (contract) { + return Promise.resolve(contract) + } + } + return this.get() + .then( this.storeContract.bind(this) ) + } + + /** + * We are changing the way how to auth to get the contract.json + * Instead of in the url, we will be putting that key value in the header + * @return {object} header + */ + get contractHeader() { + let base = {}; + if (this.opts.contractKey !== false) { + base[this.opts.contractKeyName] = this.opts.contractKey; + } + return base; + } + + /** + * Save the contract to local store + * @param {object} contract to save + * @return {object|boolean} false when its not a contract or contract on OK + */ + storeContract(contract) { + // first need to check if the contract is a contract + if (!isContract(contract)) { + throw new JsonqlValidationError(`Contract is malformed!`) + //return false; + } + let args = [contract] + if (this.opts.contractExpired) { + let expired = parseFloat(this.opts.contractExpired) + if (!isNaN(expired) && expired > 0) { + args.push(expired) + } + } + // calling the setter + this.jsonqlContract = args; + // return it + this.log('storeContract return result', contract) + return contract; + } + + /** + * return the contract from options or localStore + * @return {object} contract + */ + readContract() { + let contract = isContract(this.opts.contract) + return contract ? this.opts.contract : localStore.get(this.opts.storageKey) + } +} diff --git a/packages/@jsonql/client/src/base/http-cls.js b/packages/@jsonql/client/src/base/http-cls.js new file mode 100644 index 0000000000000000000000000000000000000000..ed632a7d5c956bce27e732e40b0c4f75cf17f24c --- /dev/null +++ b/packages/@jsonql/client/src/base/http-cls.js @@ -0,0 +1,204 @@ +// base HttpClass +import merge from 'lodash-es/merge' +import { + createQuery, + createMutation, + getNameFromPayload, + cacheBurst, + urlParams, + resultHandler +} from '../utils' +import { + isObject, + isString +} from 'jsonql-params-validator' +import { + JsonqlValidationError, + JsonqlServerError, + clientErrorsHandler +} from 'jsonql-errors' +import { + API_REQUEST_METHODS, + DEFAULT_HEADER, + JSONP_CALLBACK_NAME, + SHOW_CONTRACT_DESC_PARAM +} from 'jsonql-constants' + +// extract the one we need +const [ POST, PUT ] = API_REQUEST_METHODS + +const _log = (...args) => { + try { + if (window && window.console) { + Reflect.apply(console.log, null, args) + } + } catch(e) {} +} + +export default class HttpClass { + /** + * The opts has been check at the init stage + * @param {object} opts configuration options + */ + constructor(opts) { + // change the way how we init Fly + // flyio now become external depedencies and it makes it easier to switch + // @BUG should we run test to check if we have the windows object? + _log(opts) + this.fly = opts.Fly ? new opts.Fly() : new Fly() + // to a different environment like WeChat mini app + this.opts = opts; + this.extraHeader = {}; + // @1.2.1 for adding query to the call on the fly + this.extraParams = {}; + // this.log('start up opts', opts); + this.reqInterceptor() + this.resInterceptor() + } + + // set headers for that one call + set headers(header) { + this.extraHeader = header; + } + + /** + * Create the reusage request method + * @param {object} payload jsonql payload + * @param {object} options extra options add the request + * @param {object} headers extra headers add to the call + * @return {object} the fly request instance + */ + request(payload, options = {}, headers = {}) { + this.headers = headers; + let params = merge({}, cacheBurst(), this.extraParams) + // @TODO need to add a jsonp url and payload + if (this.opts.enableJsonp) { + let resolverName = getNameFromPayload(payload) + params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName}) + payload = payload[resolverName] + } + return this.fly.request( + this.jsonqlEndpoint, + payload, + merge({}, { method: POST, params }, options) + ) + } + + /** + * This will replace the create baseRequest method + * + */ + reqInterceptor() { + this.fly.interceptors.request.use( + req => { + const headers = this.getHeaders(); + this.log('request interceptor call', headers) + + for (let key in headers) { + req.headers[key] = headers[key]; + } + return req; + } + ) + } + + // @TODO + processJsonp(result) { + return resultHandler(result) + } + + /** + * This will be replacement of the first then call + * + */ + resInterceptor() { + const self = this; + const jsonp = self.opts.enableJsonp; + this.fly.interceptors.response.use( + res => { + this.log('response interceptor call') + self.cleanUp() + // now more processing here + // there is a problem if we throw the result.error here + // the original data is lost, so we need to do what we did before + // deal with that error in the first then instead + const result = isString(res.data) ? JSON.parse(res.data) : res.data; + if (jsonp) { + return self.processJsonp(result) + } + return resultHandler(result) + }, + // this get call when it's not 200 + err => { + self.cleanUp() + console.error(err) + throw new JsonqlServerError('Server side error', err) + } + ) + } + + /** + * Get the headers inject into the call + * @return {object} headers + */ + getHeaders() { + if (this.opts.enableAuth) { + return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader) + } + return merge({}, DEFAULT_HEADER, this.extraHeader) + } + + /** + * Post http call operation to clean up things we need + */ + cleanUp() { + this.extraHeader = {} + this.extraParams = {} + } + + /** + * GET for contract only + */ + get() { + if (this.opts.showContractDesc) { + this.extraParams = merge({}, this.extraParams, SHOW_CONTRACT_DESC_PARAM) + } + return this.request({}, {method: 'GET'}, this.contractHeader) + .then(clientErrorsHandler) + .then(result => { + this.log('get contract result', result) + // when refresh the window the result is different! + // @TODO need to check the Koa side about why is that + // also it should set a flag if we want the description or not + if (result.cache && result.contract) { + return result.contract; + } + // just the normal result + return result + }) + } + + /** + * POST to server - query + * @param {object} name of the resolver + * @param {array} args arguments + * @return {object} promise resolve to the resolver return + */ + query(name, args = []) { + return this.request(createQuery(name, args)) + .then(clientErrorsHandler) + } + + /** + * PUT to server - mutation + * @param {string} name of resolver + * @param {object} payload what it said + * @param {object} conditions what it said + * @return {object} promise resolve to the resolver return + */ + mutation(name, payload = {}, conditions = {}) { + return this.request(createMutation(name, payload, conditions), {method: PUT}) + .then(clientErrorsHandler) + } + +} diff --git a/packages/@jsonql/client/src/base/index.js b/packages/@jsonql/client/src/base/index.js new file mode 100644 index 0000000000000000000000000000000000000000..703a14a8be2dab9d3b9ce226eaddc43346d714a8 --- /dev/null +++ b/packages/@jsonql/client/src/base/index.js @@ -0,0 +1,5 @@ +// export interface +// @public +import JsonqlBaseClient from './base-cls' + +export default JsonqlBaseClient diff --git a/packages/@jsonql/client/src/core/jsonql-api-generator.js b/packages/@jsonql/client/src/core/jsonql-api-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..97e652b1e6a060265366ba37e47bc7f3ddf16874 --- /dev/null +++ b/packages/@jsonql/client/src/core/jsonql-api-generator.js @@ -0,0 +1,53 @@ +// Generate the resolver for developer to use + +// @TODO when enableAuth we need to add one extra check +// before the resolver call make it to the core +// which is checking the login state, if the developer +// is calling a private method without logging in +// then we should throw the JsonqlForbiddenError at this point +// instead of making a round trip to the server +import { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants' +import { validateAsync } from 'jsonql-params-validator' +import { + JsonqlValidationError, + JsonqlError, + clientErrorsHandler, + finalCatch +} from 'jsonql-errors' + +import methodsGenerator from './methods-generator' + +/** + * @param {object} jsonqlInstance jsonql class instance + * @param {object} config options + * @param {object} contract the contract + * @param {object} ee eventEmitter + * @return {object} constructed functions call + */ +const generator = (jsonqlInstance, config, contract, ee) => { + // V1.3.0 - now everything wrap inside this method + let obj = methodsGenerator(jsonqlInstance, ee, config, contract) + // create the rest of the methods + if (config.enableAuth) { + /** + * new method to allow retrieve the current login user data + * @return {*} userdata + */ + obj.userdata = () => jsonqlInstance.userdata; + } + // allow getting the token for valdiate agains the socket + obj.getToken = () => jsonqlInstance.rawAuthToken; + // this will pass to the ws-client if needed + // obj.eventEmitter = ee; + // this will require a param + if (config.exposeContract) { + obj.getContract = () => jsonqlInstance.get() + } + // this is for the ws to use later + obj.eventEmitter = ee; + obj.version = '__VERSION__'; + // output + return obj; +}; + +export default generator; diff --git a/packages/@jsonql/client/src/core/jsonql-static-generator.js b/packages/@jsonql/client/src/core/jsonql-static-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..c56d4b80b97cd0e30db74f79d4e126c9f1c8fe71 --- /dev/null +++ b/packages/@jsonql/client/src/core/jsonql-static-generator.js @@ -0,0 +1,122 @@ +// This generator will use the old style +// with default methods +import { RESULT_PROP_NAME, ERROR_PROP_NAME } from 'jsonql-constants' + +import methodsGenerator from './methods-generator' +import { createEvt } from '../utils' + + +/** + * Group all the same methods together + * @param {object} ee event emitter + * @param {string} type query, mutation or auth + * @param {string} resolverName use as the guide + * @param {array} args from the call + * @return {function} the handler itself + */ +const handler = (ee, type) => { + // we don't run validate here because we want until the contract is ready + return (resolverName, ...args) => ( + new Promise((resolver, rejecter) => { + // this are the callbacks + ee.$only(createEvt(type, resolverName, RESULT_PROP_NAME), resolver) + ee.$only(createEvt(type, resolverName, ERROR_PROP_NAME), rejecter) + // this is the main call + ee.$trigger(type, { resolverName, args }) + }) + ) +} + +/** + * @param {object} ee eventEmitter + * @param {object} contract the map + * @param {object} config configuration + */ +const validateRegisteredEvents = (ee, contract, config) => { + const storedEvt = ee.$queues; + const debug = config.debugOn; + if (debug) { + console.info('(validateRegisteredEvents)', 'storedEvt', storedEvt) + } + storedEvt.forEach(args => { + let [type, payload] = args; + let { resolverName } = payload; + if (debug) { + console.info('(validateRegisteredEvents)', type, resolverName) + } + if (!contract[type][resolverName]) { + throw new Error(`${type}.${resolverName} not existed in contract!`) + } + }) +} + +/** + * set up all the event handlers once the contract is ready + * @param {object} jsonqlInstance what the name said + * @param {object} ee event emitter + * @param {object} config the configuration + * @param {object} contract the map + * @return {void} nothing + */ +function setupEventHandlers(jsonqlInstance, ee, config, contract) { + let methods = methodsGenerator(jsonqlInstance, ee, config, contract) + validateRegisteredEvents(ee, contract, config) + // create handler + for (let type in methods) { + // setup event listeners - only one listener per type + ee.$only(type, function({resolverName, args}) { + if (methods[type][resolverName]) { + Reflect.apply(methods[type][resolverName], null, args) + .then(result => { + ee.$trigger(createEvt(type, resolverName, RESULT_PROP_NAME), result) + }) + .catch(err => { + ee.$trigger(createEvt(type, resolverName, ERROR_PROP_NAME), err) + }) + } else { + console.error(`${resolverName} is not defined in the contract!`) + } + }) + } + // all done now release the queue if any + setTimeout(() => { + ee.$suspend = false; + }, 1) +} + +/** + * @param {object} jsonqlInstance jsonql class instance + * @param {object} config options + * @param {object} contractPromise an unresolve promise + * @param {object} ee eventEmitter + * @return {object} constructed functions call + */ +const generator = (jsonqlInstance, config, contractPromise, ee) => { + ee.$suspend = true; // hold all the calls + // wait for the promise to resolve + contractPromise.then(contract => { + setupEventHandlers(jsonqlInstance, ee, config, contract) + }) + // construct the api + let obj = { + query: handler(ee, 'query'), + mutation: handler(ee, 'mutation'), + auth: handler(ee, 'auth') + } + // allow getting the token for valdiate agains the socket + obj.getToken = () => jsonqlInstance.rawAuthToken; + // this will pass to the ws-client if needed + // obj.eventEmitter = ee; + // this will require a param + if (config.exposeContract) { + obj.getContract = () => jsonqlInstance.get() + } + if (config.enableAuth) { + obj.userdata = () => jsonqlInstance.userdata; + } + obj.version = '__VERSION__'; + // output + return obj; +} + +export default generator; diff --git a/packages/@jsonql/client/src/core/methods-generator.js b/packages/@jsonql/client/src/core/methods-generator.js new file mode 100644 index 0000000000000000000000000000000000000000..d4309924b2175edd5a157691bb06e3abb2a4323c --- /dev/null +++ b/packages/@jsonql/client/src/core/methods-generator.js @@ -0,0 +1,113 @@ +// breaking out the inner methods generator in here +import { validateAsync } from 'jsonql-params-validator' +import { + JsonqlValidationError, + JsonqlError, + clientErrorsHandler, + finalCatch +} from 'jsonql-errors' +import { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants' + +/** + * generate authorisation specific methods + * @param {object} jsonqlInstance instance of this + * @param {string} name of method + * @param {object} opts configuration + * @param {object} contract to match + * @return {function} for use + */ +const authMethodGenerator = (jsonqlInstance, name, opts, contract) => { + return (...args) => { + const params = contract.auth[name].params; + const values = params.map((p, i) => args[i]) + const header = args[params.length] || {}; + return validateAsync(args, params) + .then(() => jsonqlInstance + .query + .apply(jsonqlInstance, [name, values, header]) + ) + .catch(finalCatch) + } +} + +/** + * Here just generate the methods calls + * @param {object} jsonqlInstance what it said + * @param {object} ee event emitter + * @param {object} config configuration + * @param {object} contract the map + * @return {object} with mapped methods + */ +export default function methodsGenerator(jsonqlInstance, ee, config, contract) { + let obj = {query: {}, mutation: {}} + // process the query first + for (let queryFn in contract.query) { + // to keep it clean we use a param to id the auth method + // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn; + // generate the query method + obj.query[queryFn] = (...args) => { + const params = contract.query[queryFn].params; + const _args = params.map((param, i) => args[i]) + // debug('query', queryFn, _params); + // @TODO this need to change + // the +1 parameter is the extra headers we want to pass + const header = args[params.length] || {}; + // @TODO validate against the type + return validateAsync(_args, params) + .then(() => jsonqlInstance + .query + .apply(jsonqlInstance, [queryFn, _args, header]) + ) + .catch(finalCatch) + } + } + // process the mutation, the reason the mutation has a fixed number of parameters + // there is only the payload, and conditions parameters + // plus a header at the end + for (let mutationFn in contract.mutation) { + obj.mutation[mutationFn] = (payload, conditions, header = {}) => { + const args = [payload, conditions]; + const params = contract.mutation[mutationFn].params; + return validateAsync(args, params) + .then(() => jsonqlInstance + .mutation + .apply(jsonqlInstance, [mutationFn, payload, conditions, header]) + ) + .catch(finalCatch) + } + } + // there is only one call issuer we want here + if (config.enableAuth && contract.auth) { + obj.auth = {} // v1.3.1 add back the auth prop name + const { loginHandlerName, logoutHandlerName } = config; + if (contract.auth[loginHandlerName]) { + // changing to the name the config specify + obj.auth[loginHandlerName] = (...args) => { + const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract) + return fn.apply(null, args) + .then(jsonqlInstance.postLoginAction) + .then(token => { + ee.$trigger(ISSUER_NAME, token) + return token; + }) + } + } + if (contract.auth[logoutHandlerName]) { + obj.auth[logoutHandlerName] = (...args) => { + const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract) + return fn.apply(null, args) + .then(jsonqlInstance.postLogoutAction) + .then(r => { + ee.$trigger(LOGOUT_NAME, r) + return r; + }) + } + } else { + obj.auth[logoutHandlerName] = () => { + jsonqlInstance.postLogoutAction(KEY_WORD) + ee.$trigger(LOGOUT_NAME, KEY_WORD) + } + } + } + return obj; +} diff --git a/packages/@jsonql/client/src/ee.js b/packages/@jsonql/client/src/ee.js new file mode 100644 index 0000000000000000000000000000000000000000..f4835072d48d2d8d42c1a7ea6c4c9b71f7b09df0 --- /dev/null +++ b/packages/@jsonql/client/src/ee.js @@ -0,0 +1,10 @@ +// this will generate a event emitter and will be use everywhere +import NBEventService from 'nb-event-service' +// output +export default function(debugOn) { + let logger = debugOn ? (...args) => { + args.unshift('[NBS]') + console.log.apply(null, args) + }: undefined; + return new NBEventService({ logger }) +} diff --git a/packages/@jsonql/client/src/index.js b/packages/@jsonql/client/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..2653e67438d451e3a73e001b6b451d534787621c --- /dev/null +++ b/packages/@jsonql/client/src/index.js @@ -0,0 +1,11 @@ + +import jsonqlAsync from './jsonql-async' +import jsonqlSync from './jsonql-sync' + +import ee from './ee' + +export { + jsonqlAsync, + jsonqlSync, + ee +} diff --git a/packages/@jsonql/client/src/jsonql-async.js b/packages/@jsonql/client/src/jsonql-async.js new file mode 100644 index 0000000000000000000000000000000000000000..5fc759cff1b1b85b48ab67f4dc35ad7ecb04bec7 --- /dev/null +++ b/packages/@jsonql/client/src/jsonql-async.js @@ -0,0 +1,27 @@ +// this is new for the flyio and normalize the name from now on +import JsonqlBaseClient from './base' +import generator from './core/jsonql-api-generator' +import { checkOptionsAsync } from './options' +import { getContractFromConfig } from './utils' + +/** + * Main interface for jsonql fetch api + * @param {object} config + * @param {object} Fly this is really pain in the backside ... long story + * @return {object} jsonql client + */ +export default function(ee, config = {}, Fly = null) { + return checkOptionsAsync(config) + .then(opts => ( + { + baseClient: new JsonqlBaseClient(opts, Fly), + opts: opts + } + )) + .then( ({baseClient, opts}) => ( + getContractFromConfig(baseClient, opts.contract) + .then(contract => generator(baseClient, opts, contract, ee) + ) + ) + ) +} diff --git a/packages/@jsonql/client/src/jsonql-sync.js b/packages/@jsonql/client/src/jsonql-sync.js new file mode 100644 index 0000000000000000000000000000000000000000..4d71bdf40f4ccc0371f484b3b097c122db9ce0e6 --- /dev/null +++ b/packages/@jsonql/client/src/jsonql-sync.js @@ -0,0 +1,20 @@ +// this will be the sync version +import JsonqlBaseClient from './base' +import generator from './core/jsonql-api-generator' +import { checkOptions } from './options' +import ee from './ee' + +/** + * when the client contains a valid contract + * @param {object} config + * @param {object} Fly the fly client + * @return {object} the client + */ +export default function jsonqlSync(ee, config, Fly) { + const { contract } = config; + const opts = checkOptions(config) + + const jsonqlBase = new JsonqlBaseClient(opts, Fly) + + return generator(jsonqlBase, opts, contract, ee) +} diff --git a/packages/@jsonql/client/src/jsonql-utils.js b/packages/@jsonql/client/src/jsonql-utils.js new file mode 100644 index 0000000000000000000000000000000000000000..ed715d81f304ab72c48078a67d9da359d83553af --- /dev/null +++ b/packages/@jsonql/client/src/jsonql-utils.js @@ -0,0 +1,1367 @@ +// break it out on its own because +// it's building from the lodash-es from scratch +// according to this discussion https://github.com/lodash/lodash/issues/3298 + +/** + * using just the map reduce to chain multiple functions together + * @param {function} mainFn the init function + * @param {array} moreFns as many as you want to take the last value and return a new one + * @return {function} accept value for the mainFn + */ +var chainFns = function (mainFn) { + var moreFns = [], len = arguments.length - 1; + while ( len-- > 0 ) moreFns[ len ] = arguments[ len + 1 ]; + + return ( + function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return ( + moreFns.reduce(function (value, nextFn) { return ( + Reflect.apply(nextFn, null, [value]) + ); }, Reflect.apply(mainFn, null, args)) + ); + } +); +}; + +/** + * previously we already make sure the order of the namespaces + * and attach the auth client to it + * @param {array} promises array of unresolved promises + * @return {object} promise resolved with the array of promises resolved results + */ +function chainPromises(promises) { + return promises.reduce(function (promiseChain, currentTask) { return ( + promiseChain.then(function (chainResults) { return ( + currentTask.then(function (currentResult) { return ( + chainResults.concat( [currentResult]) + ); }) + ); }) + ); }, Promise.resolve([])) +} + +/** + * this is essentially the same as the injectToFn + * but this will not allow overwrite and set the setter and getter + * @param {object} obj to get injected + * @param {string} name of the property + * @param {function} setter for set + * @param {function} [getter=null] for get default return null fn + * @return {object} the injected obj + */ +function objDefineProps(obj, name, setter, getter) { + if ( getter === void 0 ) getter = null; + + if (Object.getOwnPropertyDescriptor(obj, name) === undefined) { + Object.defineProperty(obj, name, { + set: setter, + get: getter === null ? function() { return null; } : getter + }); + } + return obj +} + +/** + * After the user login we will use this Object.define add a new property + * to the resolver with the decoded user data + * @param {function} resolver target resolver + * @param {string} name the name of the object to get inject also for checking + * @param {object} data to inject into the function static interface + * @param {boolean} [overwrite=false] if we want to overwrite the existing data + * @return {function} added property resolver + */ +function injectToFn(resolver, name, data, overwrite) { + if ( overwrite === void 0 ) overwrite = false; + + var check = Object.getOwnPropertyDescriptor(resolver, name); + if (overwrite === false && check !== undefined) { + // console.info(`NOT INJECTED`) + return resolver; + } + /* this will throw error! + if (overwrite === true && check !== undefined) { + delete resolver[name] // delete this property + } + */ + // console.info(`INJECTED`) + Object.defineProperty(resolver, name, { + value: data, + writable: overwrite // if its set to true then we should able to overwrite it + }); + + return resolver; +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +/** Used for built-in method references. */ +var objectProto$1 = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString$1 = objectProto$1.toString; + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString$1.call(value); +} + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto$2 = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; +} + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); +} + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +/** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ +function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); +} + +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); +} + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ +function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +/** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ +function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +/** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function asciiToArray(string) { + return string.split(''); +} + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/** Used to compose unicode character classes. */ +var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f', + reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', + rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', + rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, + rsVarRange$1 = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange$1 + ']', + rsCombo = '[' + rsComboRange$1 + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange$1 + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange$1 + ']?', + rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function unicodeToArray(string) { + return string.match(reUnicode) || []; +} + +/** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); +} + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +/** Used to match leading and trailing whitespace. */ +var reTrim = /^\s+|\s+$/g; + +/** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ +function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); +} + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); +} + +// bunch of generic helpers + +/** + * DIY in Array + * @param {array} arr to check from + * @param {*} value to check against + * @return {boolean} true on found + */ +var inArray = function (arr, value) { return !!arr.filter(function (a) { return a === value; }).length; }; + +/** + * @param {object} obj for search + * @param {string} key target + * @return {boolean} true on success + */ +var isKeyInObject = function(obj, key) { + var keys = Object.keys(obj); + return inArray(keys, key) +}; + +/** + * create a event name + * @param {string[]} args + * @return {string} event name for use + */ +var createEvt = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return args.join('_'); +}; + +/** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ +var timestamp = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; +}; + +/** + * construct a url with query parameters + * @param {string} url to append + * @param {object} params to append to url + * @return {string} url with appended params + */ +var urlParams = function (url, params) { + var parts = []; + for (var key in params) { + parts.push( [key, params[key]].join('=') ); + } + return [url, parts.join('&')].join('?') +}; + +/** + * construct a url with cache burster + * @param {string} url to append to + * @return {object} _cb key timestamp + */ +var cacheBurstUrl = function (url) { return urlParams(url, cacheBurst()); }; + +/** + * @return {object} _cb as key with timestamp + */ +var cacheBurst = function () { return ({ _cb: timestamp() }); }; + +/** + * From underscore.string library + * @BUG there is a bug here with the non-standard name start with _ + * @param {string} str string + * @return {string} dasherize string + */ +var dasherize = function (str) { return ( + trim(str) + .replace(/([A-Z])/g, '-$1') + .replace(/[-_\s]+/g, '-') + .toLowerCase() +); }; + +/** + * simple util method to get the value + * @param {string} name of the key + * @param {object} obj to take value from + * @return {*} the object value id by name or undefined + */ +var getConfigValue = function (name, obj) { return ( + obj && isPlainObject(obj) ? ( (name in obj) ? obj[name] : undefined ) : undefined +); }; + +/** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ +var isNotEmpty = function(param) { + return param !== undefined && param !== false && param !== null && trim(param) !== ''; +}; + +// the core stuff to id if it's calling with jsonql +var DATA_KEY = 'data'; +var ERROR_KEY = 'error'; + +// @TODO remove this is not in use +// export const CLIENT_CONFIG_FILE = '.clients.json'; +// export const CONTRACT_CONFIG_FILE = 'jsonql-contract-config.js'; +// type of resolvers +var QUERY_NAME = 'query'; +var MUTATION_NAME = 'mutation'; +var SOCKET_NAME = 'socket'; +// for calling the mutation +var PAYLOAD_PARAM_NAME = 'payload'; +var CONDITION_PARAM_NAME = 'condition'; +var RESOLVER_PARAM_NAME = 'resolverName'; +var QUERY_ARG_NAME = 'args'; + +// methods allow +var API_REQUEST_METHODS = ['POST', 'PUT']; +var NO_STATUS_CODE = -1; + +/** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + +var isBrowser = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; +}; + +var isNode = function () { + try { + if (!isBrowser() && global$1) { + return true; + } + } catch(e) {} + return false; +}; + +function whereAmI() { + if (isBrowser()) { + return 'browser' + } + if (isNode()) { + return 'node' + } + return 'unknown' +} + +// The base Error of all + +var JsonqlBaseError = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + } + + if ( Error ) JsonqlBaseError.__proto__ = Error; + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI() + }; + + return JsonqlBaseError; +}(Error)); + +/** + * This is a custom error to throw when could not find the resolver + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ +var JsonqlResolverNotFoundError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlResolverNotFoundError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlResolverNotFoundError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlResolverNotFoundError); + } + } + + if ( JsonqlBaseError ) JsonqlResolverNotFoundError.__proto__ = JsonqlBaseError; + JsonqlResolverNotFoundError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlResolverNotFoundError.prototype.constructor = JsonqlResolverNotFoundError; + + var staticAccessors = { statusCode: { configurable: true },name: { configurable: true } }; + + staticAccessors.statusCode.get = function () { + return 404; + }; + + staticAccessors.name.get = function () { + return 'JsonqlResolverNotFoundError'; + }; + + Object.defineProperties( JsonqlResolverNotFoundError, staticAccessors ); + + return JsonqlResolverNotFoundError; +}(JsonqlBaseError)); + +// custom validation error class +// when validaton failed +var JsonqlValidationError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) JsonqlValidationError.__proto__ = JsonqlBaseError; + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; +}(JsonqlBaseError)); + +/** + * This is a custom error to throw whenever a error happen inside the jsonql + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ +var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlError); + // this.detail = this.stack; + } + } + + if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; + JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlError.prototype.constructor = JsonqlError; + + var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlError'; + }; + + staticAccessors.statusCode.get = function () { + return NO_STATUS_CODE; + }; + + Object.defineProperties( JsonqlError, staticAccessors ); + + return JsonqlError; +}(JsonqlBaseError)); + +// split the contract into the node side and the generic side +/** + * Check if the json is a contract file or not + * @param {object} contract json object + * @return {boolean} true + */ +function checkIsContract(contract) { + return isPlainObject(contract) + && ( + isKeyInObject(contract, QUERY_NAME) + || isKeyInObject(contract, MUTATION_NAME) + || isKeyInObject(contract, SOCKET_NAME) + ) +} + +/** + * Ported from jsonql-params-validator but different + * if we don't find the socket part then return false + * @param {object} contract the contract object + * @return {object|boolean} false on failed + */ +function extractSocketPart(contract) { + if (isKeyInObject(contract, 'socket')) { + return contract.socket; + } + return false; +} + +/** + * @BUG we should check the socket part instead of expect the downstream to read the menu! + * We only need this when the enableAuth is true otherwise there is only one namespace + * @param {object} contract the socket part of the contract file + * @param {boolean} [fallback=false] this is a fall back option for old code + * @return {object} 1. remap the contract using the namespace --> resolvers + * 2. the size of the object (1 all private, 2 mixed public with private) + * 3. which namespace is public + */ +function groupByNamespace(contract, fallback) { + if ( fallback === void 0 ) fallback = false; + + var socket = extractSocketPart(contract); + if (socket === false) { + if (fallback) { + return contract; // just return the whole contract + } + throw new JsonqlError("socket not found in contract!") + } + var nspSet = {}; + var size = 0; + var publicNamespace; + for (var resolverName in socket) { + var params = socket[resolverName]; + var namespace = params.namespace; + if (namespace) { + if (!nspSet[namespace]) { + ++size; + nspSet[namespace] = {}; + } + nspSet[namespace][resolverName] = params; + if (!publicNamespace) { + if (params.public) { + publicNamespace = namespace; + } + } + } + } + return { size: size, nspSet: nspSet, publicNamespace: publicNamespace } +} + +/** + * Extract the args from the payload + * @param {object} payload to work with + * @param {string} type of call + * @return {array} args + */ +function extractArgsFromPayload(payload, type) { + switch (type) { + case QUERY_NAME: + return payload[QUERY_ARG_NAME]; + case MUTATION_NAME: + return [ + payload[PAYLOAD_PARAM_NAME], + payload[CONDITION_PARAM_NAME] + ]; + default: + throw new JsonqlError(("Unknown " + type + " to extract argument from!")) + } +} + +/** + * Like what the name said + * @param {object} contract the contract json + * @param {string} type query|mutation + * @param {string} name of the function + * @return {object} the params part of the contract + */ +function extractParamsFromContract(contract, type, name) { + try { + var result = contract[type][name]; + // debug('extractParamsFromContract', result) + if (!result) { + // debug(name, type, contract) + throw new JsonqlResolverNotFoundError(name, type) + } + return result; + } catch(e) { + throw new JsonqlResolverNotFoundError(name, e) + } +} + +// ported from jsonql-params-validator + +/** + * make sure it's an object (it was call formatPayload but it doesn't make sense) + * @param {*} payload the object comes in could be string based + * @return {object} the transformed payload + */ +var toPayload = function (payload) { return isString(payload) ? JSON.parse(payload) : payload; }; + +/** + * @param {*} args arguments to send + *@return {object} formatted payload + */ +var formatPayload = function (args) { + var obj; + + return ( + ( obj = {}, obj[QUERY_ARG_NAME] = args, obj ) +); +}; + +/** + * Get name from the payload (ported back from jsonql-koa) + * @param {*} payload to extract from + * @return {string} name + */ +function getNameFromPayload(payload) { + return Object.keys(payload)[0] +} + +/** + * @param {string} resolverName name of function + * @param {array} [args=[]] from the ...args + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ +function createQuery(resolverName, args, jsonp) { + var obj; + + if ( args === void 0 ) args = []; + if ( jsonp === void 0 ) jsonp = false; + if (isString(resolverName) && isArray(args)) { + var payload = formatPayload(args); + if (jsonp === true) { + return payload; + } + return ( obj = {}, obj[resolverName] = payload, obj ) + } + throw new JsonqlValidationError("[createQuery] expect resolverName to be string and args to be array!", { resolverName: resolverName, args: args }) +} + +// string version of the above +function createQueryStr(resolverName, args, jsonp) { + if ( args === void 0 ) args = []; + if ( jsonp === void 0 ) jsonp = false; + + return JSON.stringify(createQuery(resolverName, args, jsonp)) +} + +/** + * @param {string} resolverName name of function + * @param {*} payload to send + * @param {object} [condition={}] for what + * @param {boolean} [jsonp = false] add v1.3.0 to koa + * @return {object} formatted argument + */ +function createMutation(resolverName, payload, condition, jsonp) { + var obj; + + if ( condition === void 0 ) condition = {}; + if ( jsonp === void 0 ) jsonp = false; + var _payload = {}; + _payload[PAYLOAD_PARAM_NAME] = payload; + _payload[CONDITION_PARAM_NAME] = condition; + if (jsonp === true) { + return _payload; + } + if (isString(resolverName)) { + return ( obj = {}, obj[resolverName] = _payload, obj ) + } + throw new JsonqlValidationError("[createMutation] expect resolverName to be string!", { resolverName: resolverName, payload: payload, condition: condition }) +} + +// string version of above +function createMutationStr(resolverName, payload, condition, jsonp) { + if ( condition === void 0 ) condition = {}; + if ( jsonp === void 0 ) jsonp = false; + + return JSON.stringify(createMutation(resolverName, payload, condition, jsonp)) +} + +/** + * Further break down from method below for use else where + * @param {string} resolverName name of fn + * @param {object} payload payload + * @return {object|boolean} false on failed + */ +function getQueryFromArgs(resolverName, payload) { + var obj; + + if (resolverName && isPlainObject(payload)) { + var args = payload[resolverName]; + if (args[QUERY_ARG_NAME]) { + return ( obj = {}, obj[RESOLVER_PARAM_NAME] = resolverName, obj[QUERY_ARG_NAME] = args[QUERY_ARG_NAME], obj ) + } + } + return false; +} + +/** + * Share function so no repeat + * @param {object} payload the payload from client + * @param {function} processor the last get result method + * @return {*} result processed result + */ +function processPayload(payload, processor) { + var p = toPayload(payload); + var resolverName = getNameFromPayload(p); + return Reflect.apply(processor, null, [resolverName, p]) +} + +/** + * extra the payload back + * @param {*} payload from http call + * @return {object} resolverName and args + */ +function getQueryFromPayload(payload) { + var result = processPayload(payload, getQueryFromArgs); + if (result !== false) { + return result; + } + throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload) +} + +/** + * Further break down from method below for use else where + * @param {string} resolverName name of fn + * @param {object} payload payload + * @return {object|boolean} false on failed + */ +function getMutationFromArgs(resolverName, payload) { + var obj; + + if (resolverName && isPlainObject(payload)) { + var args = payload[resolverName]; + if (args) { + return ( obj = {}, obj[RESOLVER_PARAM_NAME] = resolverName, obj[PAYLOAD_PARAM_NAME] = args[PAYLOAD_PARAM_NAME], obj[CONDITION_PARAM_NAME] = args[CONDITION_PARAM_NAME], obj ) + } + } + return false; +} + +/** + * @param {object} payload + * @return {object} resolverName, payload, conditon + */ +function getMutationFromPayload(payload) { + var result = processPayload(payload, getMutationFromArgs); + + if (result !== false) { + return result; + } + throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload) +} + +// break up from node-middleware +/** + * getting what is calling after the above check + * @param {string} method of call + * @return {mixed} false on failed + */ +var getCallMethod = function (method) { + var POST = API_REQUEST_METHODS[0]; + var PUT = API_REQUEST_METHODS[1]; + switch (true) { + case method === POST: + return QUERY_NAME; + case method === PUT: + return MUTATION_NAME; + default: + return false; + } +}; + +/** + * wrapper method + * @param {mixed} result of fn return + * @return {string} stringify data + */ +var packResult = function(result) { + var obj; + + return JSON.stringify(( obj = {}, obj[DATA_KEY] = result, obj )) +}; + +/** + * wrapper method - the output is trying to match up the structure of the Error sub class + * @param {mixed} detail of fn error + * @param {string} [className=JsonqlError] the errorName + * @param {number} [statusCode=500] the original error code + * @return {string} stringify error + */ +var packError = function(detail, className, statusCode, message) { + var obj; + + if ( className === void 0 ) className = 'JsonqlError'; + if ( statusCode === void 0 ) statusCode = 500; + if ( message === void 0 ) message = ''; + return JSON.stringify(( obj = {}, obj[ERROR_KEY] = { detail: detail, className: className, statusCode: statusCode, message: message }, obj )) +}; + +// ported from http-client + +/** + * handle the return data + * @param {object} result return from server + * @return {object} strip the data part out, or if the error is presented + */ +var resultHandler = function (result) { return ( + (isKeyInObject(result, DATA_KEY) && !isKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result +); }; + +// exportfor ES modules + +// alias +var isContract = checkIsContract; +var VERSION = '0.6.9'; + +export { VERSION, cacheBurst, cacheBurstUrl, chainFns, chainPromises, checkIsContract, createEvt, createMutation, createMutationStr, createQuery, createQueryStr, dasherize, extractArgsFromPayload, extractParamsFromContract, extractSocketPart, formatPayload, getCallMethod, getConfigValue, getMutationFromArgs, getMutationFromPayload, getNameFromPayload, getQueryFromArgs, getQueryFromPayload, groupByNamespace, inArray, injectToFn, isContract, isKeyInObject, isNotEmpty, objDefineProps, packError, packResult, resultHandler, timestamp, toPayload, urlParams }; diff --git a/packages/@jsonql/client/src/options/base-options.js b/packages/@jsonql/client/src/options/base-options.js new file mode 100644 index 0000000000000000000000000000000000000000..cf3de7a4ac80fe2eceec88653b4a2ae6166e9352 --- /dev/null +++ b/packages/@jsonql/client/src/options/base-options.js @@ -0,0 +1,66 @@ +// all the client configuration options here +import { + JSONQL_PATH, + CONTENT_TYPE, + BEARER, + CLIENT_STORAGE_KEY, + CLIENT_AUTH_KEY, + CONTRACT_KEY_NAME, + AUTH_HEADER, + ISSUER_NAME, + LOGOUT_NAME, + BOOLEAN_TYPE, + STRING_TYPE, + NUMBER_TYPE, + DEFAULT_HEADER +} from 'jsonql-constants' +import { createConfig } from 'jsonql-params-validator' +export const constProps = { + contract: false, + MUTATION_ARGS: ['name', 'payload', 'conditions'], // this seems wrong? + CONTENT_TYPE, + BEARER, + AUTH_HEADER +} + +// grab the localhost name and put into the hostname as default +const getHostName = () => ( + [window.location.protocol, window.location.host].join('//') +) + +export const appProps = { + + hostname: createConfig(getHostName(), [STRING_TYPE]), // required the hostname + jsonqlPath: createConfig(JSONQL_PATH, [STRING_TYPE]), // The path on the server + + loginHandlerName: createConfig(ISSUER_NAME, [STRING_TYPE]), + logoutHandlerName: createConfig(LOGOUT_NAME, [STRING_TYPE]), + // add to koa v1.3.0 - this might remove in the future + enableJsonp: createConfig(false, [BOOLEAN_TYPE]), + enableAuth: createConfig(false, [BOOLEAN_TYPE]), + // enable useJwt by default + useJwt: createConfig(true, [BOOLEAN_TYPE]), + + // the header + // v1.2.0 we are using this option during the dev + // so it won't save anything to the localstorage and fetch a new contract + // whenever the browser reload + useLocalstorage: createConfig(true, [BOOLEAN_TYPE]), // should we store the contract into localStorage + storageKey: createConfig(CLIENT_STORAGE_KEY, [STRING_TYPE]),// the key to use when store into localStorage + authKey: createConfig(CLIENT_AUTH_KEY, [STRING_TYPE]),// the key to use when store into the sessionStorage + contractExpired: createConfig(0, [NUMBER_TYPE]),// -1 always fetch contract, + // 0 never expired, + // > 0 then compare the timestamp with the current one to see if we need to get contract again + // useful during development + keepContract: createConfig(true, [BOOLEAN_TYPE]), + exposeContract: createConfig(false, [BOOLEAN_TYPE]), + // @1.2.1 new option for the contract-console to fetch the contract with description + showContractDesc: createConfig(false, [BOOLEAN_TYPE]), + contractKey: createConfig(false, [BOOLEAN_TYPE]), // if the server side is lock by the key you need this + contractKeyName: createConfig(CONTRACT_KEY_NAME, [STRING_TYPE]), // same as above they go in pairs + enableTimeout: createConfig(false, [BOOLEAN_TYPE]), // @TODO + timeout: createConfig(5000, [NUMBER_TYPE]), // 5 seconds + returnInstance: createConfig(false, [BOOLEAN_TYPE]), + allowReturnRawToken: createConfig(false, [BOOLEAN_TYPE]), + debugOn: createConfig(false, [BOOLEAN_TYPE]) +} diff --git a/packages/@jsonql/client/src/options/check-options-async.js b/packages/@jsonql/client/src/options/check-options-async.js new file mode 100644 index 0000000000000000000000000000000000000000..b16be5b17b90974ea73030f5adc8e69b9279a43e --- /dev/null +++ b/packages/@jsonql/client/src/options/check-options-async.js @@ -0,0 +1,14 @@ +// we must ensure the user passing the correct options +// therefore we need to validate against the properties as well + +import { appProps, constProps } from './base-options' +import { checkConfigAsync } from 'jsonql-params-validator' + +export default function checkOptionsAsync(config) { + let { contract } = config; + return checkConfigAsync(config, appProps, constProps) + .then(opts => { + opts.contract = contract; + return opts; + }) +} diff --git a/packages/@jsonql/client/src/options/check-options.js b/packages/@jsonql/client/src/options/check-options.js new file mode 100644 index 0000000000000000000000000000000000000000..631c9792acd3dd3004898a50c54dcfd8bdc04585 --- /dev/null +++ b/packages/@jsonql/client/src/options/check-options.js @@ -0,0 +1,7 @@ +// This is for the sync version therefore we don't need to care about the contract options +import { appProps, constProps } from './base-options' +import { checkConfig } from 'jsonql-params-validator' + +export default function checkOptions(config) { + return checkConfig(config, appProps, constProps) +} diff --git a/packages/@jsonql/client/src/options/index.js b/packages/@jsonql/client/src/options/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cd452fd35ddb98de163928ad934f33d02af8216f --- /dev/null +++ b/packages/@jsonql/client/src/options/index.js @@ -0,0 +1,8 @@ +// export interface +import checkOptionsAsync from './check-options-async' +import checkOptions from './check-options' + +export { + checkOptionsAsync, + checkOptions +} diff --git a/packages/@jsonql/client/src/static-full.js b/packages/@jsonql/client/src/static-full.js new file mode 100644 index 0000000000000000000000000000000000000000..1e41b781bac8b1c6d8af75a0690b7f7eb94a9b76 --- /dev/null +++ b/packages/@jsonql/client/src/static-full.js @@ -0,0 +1,8 @@ +// This is the static version that build with the Fly for Browser +import Fly from 'flyio/dist/npm/fly' +import jsonqlStaticClient from './static' + +// this is the slim client without Fly +export default function jsonqlStaticClientFull(config = {}) { + return jsonqlStaticClient(Fly, config) +} diff --git a/packages/@jsonql/client/src/static.js b/packages/@jsonql/client/src/static.js new file mode 100644 index 0000000000000000000000000000000000000000..bc502704c6efae13aeed8a6a8cff669860ab3ac4 --- /dev/null +++ b/packages/@jsonql/client/src/static.js @@ -0,0 +1,26 @@ +// this is the new Event base interface +// the export will be different and purposely design for framework that +// is very hard to use Promise such as Vue +import jsonqlStaticGenerator from './core/jsonql-static-generator' +import JsonqlBaseClient from './base' +import { checkOptions } from './options' +import { getContractFromConfig } from './utils' +import getEventEmitter from './ee' +/** + * this is the slim client without Fly, you pick the version of Fly to use + * This is a breaking change because it swap the input positions + * @param {object} Fly fly.js + * @param {object} config configuration + * @return {object} the jsonql client instance + */ +export default function jsonqlStaticClient(Fly, config = {}) { + const { contract } = config; + const opts = checkOptions(config) + const jsonqlBase = new JsonqlBaseClient(opts, Fly) + const contractPromise = getContractFromConfig(jsonqlBase, contract) + const ee = getEventEmitter(opts.debugOn) + // finally + let methods = jsonqlStaticGenerator(jsonqlBase, opts, contractPromise, ee) + methods.eventEmitter = ee; + return methods; +} diff --git a/packages/@jsonql/client/src/stores/index.js b/packages/@jsonql/client/src/stores/index.js new file mode 100644 index 0000000000000000000000000000000000000000..6f9c1e3e9eec77342407593f4c50a7483eafd776 --- /dev/null +++ b/packages/@jsonql/client/src/stores/index.js @@ -0,0 +1,7 @@ +// export store interface +import localStoreEngine from './local-store' +import sessionStoreEngine from './session-store' + +// export back the raw version for development purposes +export const localStore = localStoreEngine +export const sessionStore = sessionStoreEngine diff --git a/packages/@jsonql/client/src/stores/local-store.js b/packages/@jsonql/client/src/stores/local-store.js new file mode 100644 index 0000000000000000000000000000000000000000..8b15b31538ccd7a0c121db984cfa9fdae05bcb24 --- /dev/null +++ b/packages/@jsonql/client/src/stores/local-store.js @@ -0,0 +1,17 @@ +// sort of persist on the user side +import engine from 'store/src/store-engine' + +import localStorage from 'store/storages/localStorage' +import cookieStorage from 'store/storages/cookieStorage' + +import defaultPlugin from 'store/plugins/defaults' +import expiredPlugin from 'store/plugins/expire' +import eventsPlugin from 'store/plugins/events' +import compressionPlugin from 'store/plugins/compression' + +const storages = [localStorage, cookieStorage] +const plugins = [defaultPlugin, expiredPlugin, eventsPlugin, compressionPlugin] + +const localStore = engine.createStore(storages, plugins) + +export default localStore diff --git a/packages/@jsonql/client/src/stores/session-store.js b/packages/@jsonql/client/src/stores/session-store.js new file mode 100644 index 0000000000000000000000000000000000000000..c5a6bb7576726d507abe34616e7626e2ca53c7fb --- /dev/null +++ b/packages/@jsonql/client/src/stores/session-store.js @@ -0,0 +1,15 @@ +// session store with watch +import engine from 'store/src/store-engine' + +import sessionStorage from 'store/storages/sessionStorage' +import cookieStorage from 'store/storages/cookieStorage' + +import defaultPlugin from 'store/plugins/defaults' +import expiredPlugin from 'store/plugins/expire' + +const storages = [sessionStorage, cookieStorage] +const plugins = [defaultPlugin, expiredPlugin] + +const sessionStore = engine.createStore(storages, plugins) + +export default sessionStore diff --git a/packages/@jsonql/client/src/utils.js b/packages/@jsonql/client/src/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..3937b776039768e29762e1fa96aa8b8aacc519ff --- /dev/null +++ b/packages/@jsonql/client/src/utils.js @@ -0,0 +1,53 @@ +// take only the module part which is what we use here +// and export it again to use through out the client +// this way we avoid those that we don't want node.js module got build into the code +import { + createEvt, + + createQuery, + createMutation, + getNameFromPayload, + cacheBurst, + urlParams, + resultHandler, + + isContract, + timestamp, + inArray +} from './jsonql-utils' // this should point to the module.js +/** + * @param {object} jsonqlInstance the init instance of jsonql client + * @param {object} contract the static contract + * @return {object} contract may be from server + */ +const getContractFromConfig = function(jsonqlInstance, contract = {}) { + if (isContract(contract)) { + return Promise.resolve(contract) + } + return jsonqlInstance.getContract() +} + +// export some constants as well +// since it's only use here there is no point of adding it to the constants module +// or may be we add it back later +const ENDPOINT_TABLE = 'endpoint'; +const USERDATA_TABLE = 'userdata'; + +// export +export { + getContractFromConfig, + ENDPOINT_TABLE, + USERDATA_TABLE, + createEvt, + + createQuery, + createMutation, + getNameFromPayload, + cacheBurst, + urlParams, + resultHandler, + + isContract, + timestamp, + inArray +} diff --git a/packages/@jsonql/client/static.js b/packages/@jsonql/client/static.js new file mode 100644 index 0000000000000000000000000000000000000000..6dcd770436924ae7164ea128f2080849fda10e97 --- /dev/null +++ b/packages/@jsonql/client/static.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("debug")):"function"==typeof define&&define.amd?define(["debug"],e):(t=t||self).jsonqlClientStatic=e(t.debug)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e="application/vnd.api+json",r={Accept:e,"Content-Type":[e,"charset=utf-8"].join(";")},n=["POST","PUT"],o="continue",i="type",a="optional",u="enumv",c="args",s="checker",f="alias",l="login",p="logout",h={desc:"y"},d="No message",v="onResult",g="onError";var y="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},b="object"==typeof y&&y&&y.Object===Object&&y,m="object"==typeof self&&self&&self.Object===Object&&self,_=b||m||Function("return this")(),w=_.Symbol;function j(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r=n?t:function(t,e,r){var n=-1,o=t.length;e<0&&(e=-e>o?0:o+e),(r=r>o?o:r)<0&&(r+=o),o=e>r?0:r-e>>>0,e>>>=0;for(var i=Array(o);++n-1;);return r}(n,o),function(t,e){for(var r=t.length;r--&&H(e,t[r],0)>-1;);return r}(n,o)+1).join("")}function ot(t){return void 0===t}var it="[object Boolean]";var at="[object Number]";function ut(t){return function(t){return"number"==typeof t||$(t)&&C(t)==at}(t)&&t!=+t}var ct="[object String]";function st(t){return"string"==typeof t||!S(t)&&$(t)&&C(t)==ct}function ft(t,e){return function(r){return t(e(r))}}var lt=ft(Object.getPrototypeOf,Object),pt="[object Object]",ht=Function.prototype,dt=Object.prototype,vt=ht.toString,gt=dt.hasOwnProperty,yt=vt.call(Object);function bt(t){if(!$(t)||C(t)!=pt)return!1;var e=lt(t);if(null===e)return!0;var r=gt.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&vt.call(r)==yt}var mt,_t=function(t,e,r){for(var n=-1,o=Object(t),i=r(t),a=i.length;a--;){var u=i[mt?a:++n];if(!1===e(o[u],u,o))break}return t};var wt="[object Arguments]";function jt(t){return $(t)&&C(t)==wt}var St=Object.prototype,Ot=St.hasOwnProperty,Et=St.propertyIsEnumerable,kt=jt(function(){return arguments}())?jt:function(t){return $(t)&&Ot.call(t,"callee")&&!Et.call(t,"callee")};var At="object"==typeof exports&&exports&&!exports.nodeType&&exports,Tt=At&&"object"==typeof module&&module&&!module.nodeType&&module,xt=Tt&&Tt.exports===At?_.Buffer:void 0,qt=(xt?xt.isBuffer:void 0)||function(){return!1},Pt=9007199254740991,Ct=/^(?:0|[1-9]\d*)$/;function $t(t,e){var r=typeof t;return!!(e=null==e?Pt:e)&&("number"==r||"symbol"!=r&&Ct.test(t))&&t>-1&&t%1==0&&t-1&&t%1==0&&t<=Nt}var Ft={};Ft["[object Float32Array]"]=Ft["[object Float64Array]"]=Ft["[object Int8Array]"]=Ft["[object Int16Array]"]=Ft["[object Int32Array]"]=Ft["[object Uint8Array]"]=Ft["[object Uint8ClampedArray]"]=Ft["[object Uint16Array]"]=Ft["[object Uint32Array]"]=!0,Ft["[object Arguments]"]=Ft["[object Array]"]=Ft["[object ArrayBuffer]"]=Ft["[object Boolean]"]=Ft["[object DataView]"]=Ft["[object Date]"]=Ft["[object Error]"]=Ft["[object Function]"]=Ft["[object Map]"]=Ft["[object Number]"]=Ft["[object Object]"]=Ft["[object RegExp]"]=Ft["[object Set]"]=Ft["[object String]"]=Ft["[object WeakMap]"]=!1;var It,Rt="object"==typeof exports&&exports&&!exports.nodeType&&exports,Jt=Rt&&"object"==typeof module&&module&&!module.nodeType&&module,Mt=Jt&&Jt.exports===Rt&&b.process,Ut=function(){try{var t=Jt&&Jt.require&&Jt.require("util").types;return t||Mt&&Mt.binding&&Mt.binding("util")}catch(t){}}(),Ht=Ut&&Ut.isTypedArray,Dt=Ht?(It=Ht,function(t){return It(t)}):function(t){return $(t)&&zt(t.length)&&!!Ft[C(t)]},Lt=Object.prototype.hasOwnProperty;function Bt(t,e){var r=S(t),n=!r&&kt(t),o=!r&&!n&&qt(t),i=!r&&!n&&!o&&Dt(t),a=r||n||o||i,u=a?function(t,e){for(var r=-1,n=Array(t);++r-1},ce.prototype.set=function(t,e){var r=this.__data__,n=ae(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this};var se,fe=_["__core-js_shared__"],le=(se=/[^.]+$/.exec(fe&&fe.keys&&fe.keys.IE_PROTO||""))?"Symbol(src)_1."+se:"";var pe=Function.prototype.toString;function he(t){if(null!=t){try{return pe.call(t)}catch(t){}try{return t+""}catch(t){}}return""}var de=/^\[object .+?Constructor\]$/,ve=Function.prototype,ge=Object.prototype,ye=ve.toString,be=ge.hasOwnProperty,me=RegExp("^"+ye.call(be).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function _e(t){return!(!Wt(t)||function(t){return!!le&&le in t}(t))&&(ee(t)?me:de).test(he(t))}function we(t,e){var r=function(t,e){return null==t?void 0:t[e]}(t,e);return _e(r)?r:void 0}var je=we(_,"Map"),Se=we(Object,"create");var Oe="__lodash_hash_undefined__",Ee=Object.prototype.hasOwnProperty;var ke=Object.prototype.hasOwnProperty;var Ae="__lodash_hash_undefined__";function Te(t){var e=-1,r=null==t?0:t.length;for(this.clear();++eu))return!1;var s=i.get(t);if(s&&i.get(e))return s==e;var f=-1,l=!0,p=r&Ie?new Ne:void 0;for(i.set(t,e),i.set(e,t);++f0){if(++e>=En)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(On);function xn(t,e){return Tn(function(t,e,r){return e=Sn(void 0===e?t.length-1:e,0),function(){for(var n=arguments,o=-1,i=Sn(n.length-e,0),a=Array(i);++o1?e[n-1]:void 0,i=n>2?e[2]:void 0;for(o=qn.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,e,r){if(!Wt(r))return!1;var n=typeof e;return!!("number"==n?re(r)&&$t(e,r.length):"string"==n&&e in r)&&ie(r[e],t)}(e[0],e[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++r0))},Xn=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var e=t.replace("array.<","").replace(">","");return e.indexOf("|")?e.split("|"):[e]}return!1},Zn=function(t,e){var r=t.arg;return e.length>1?!r.filter((function(t){return!(e.length>e.filter((function(e){return!Wn(e)(t)})).length)})).length:e.length>e.filter((function(t){return!Qn(r,t)})).length},to=function(t,e){if(void 0===e&&(e=null),bt(t)){if(!e)return!0;if(Qn(e))return!e.filter((function(e){var r=t[e.name];return!(e.type.length>e.type.filter((function(t){var e;return!!ot(r)||(!1!==(e=Xn(t))?!Zn({arg:r},e):!Wn(t)(r))})).length)})).length}return!1},eo=function(t){var e=t.arg,r=t.param,n=[e];return Array.isArray(r.keys)&&r.keys.length&&n.push(r.keys),to.apply(null,n)},ro=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 406},r.name.get=function(){return"Jsonql406Error"},Object.defineProperties(e,r),e}(Error),no=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 500},r.name.get=function(){return"Jsonql500Error"},Object.defineProperties(e,r),e}(Error),oo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 401},r.name.get=function(){return"JsonqlAuthorisationError"},Object.defineProperties(e,r),e}(Error),io=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 401},r.name.get=function(){return"JsonqlContractAuthError"},Object.defineProperties(e,r),e}(Error),ao=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 500},r.name.get=function(){return"JsonqlResolverAppError"},Object.defineProperties(e,r),e}(Error),uo=function(){try{if(window||document)return!0}catch(t){}return!1},co=function(){try{if(!uo()&&y)return!0}catch(t){}return!1};var so=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.where=function(){return uo()?"browser":co()?"node":"unknown"},e}(Error),fo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={statusCode:{configurable:!0},name:{configurable:!0}};return r.statusCode.get=function(){return 404},r.name.get=function(){return"JsonqlResolverNotFoundError"},Object.defineProperties(e,r),e}(so),lo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,r),e}(Error),po=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,r),e}(Error),ho=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,t.captureStackTrace&&t.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,r),e}(Error),vo=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,r),e}(so),go=function(t){function e(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r),this.message=r[0],this.detail=r[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0},statusCode:{configurable:!0}};return r.name.get=function(){return"JsonqlError"},r.statusCode.get=function(){return-1},Object.defineProperties(e,r),e}(so),yo=function(t){function e(r,n){t.call(this,n),this.statusCode=r,this.className=e.name}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlServerError"},Object.defineProperties(e,r),e}(Error),bo=Object.freeze({Jsonql406Error:ro,Jsonql500Error:no,JsonqlAuthorisationError:oo,JsonqlContractAuthError:io,JsonqlResolverAppError:ao,JsonqlResolverNotFoundError:fo,JsonqlEnumError:lo,JsonqlTypeError:po,JsonqlCheckerError:ho,JsonqlValidationError:vo,JsonqlError:go,JsonqlServerError:yo}),mo=go,_o=function(t,e){return!!Object.keys(t).filter((function(t){return e===t})).length};function wo(t){if(_o(t,"error")){var e=t.error,r=e.className,n=e.name,o=r||n,i=e.message||d,a=e.detail||e;if(o&&bo[o])throw new bo[r](i,a);throw new mo(i,a)}return t}function jo(t){if(Array.isArray(t))throw new vo("",t);var e=t.message||d,r=t.detail||t;switch(!0){case t instanceof ro:throw new ro(e,r);case t instanceof no:throw new no(e,r);case t instanceof oo:throw new oo(e,r);case t instanceof io:throw new io(e,r);case t instanceof ao:throw new ao(e,r);case t instanceof fo:throw new fo(e,r);case t instanceof lo:throw new lo(e,r);case t instanceof po:throw new po(e,r);case t instanceof ho:throw new ho(e,r);case t instanceof vo:throw new vo(e,r);case t instanceof yo:throw new yo(e,r);default:throw new go(e,r)}}function So(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];try{window&&window.console&&Reflect.apply(console.log,console,t)}catch(t){}}var Oo=function(t,e){var r;switch(!0){case"object"===t:return!eo(e);case"array"===t:return!Qn(e.arg);case!1!==(r=Xn(t)):return!Zn(e,r);default:return!Wn(t)(e.arg)}},Eo=function(t,e){return ot(t)?!0!==e.optional||ot(e.defaultvalue)?null:e.defaultvalue:t},ko=function(t,e,r){var n;void 0===r&&(r=!1);var o=function(t,e){if(!Qn(e))throw new go("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===e.length)return[];if(!Qn(t))throw new go("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==e.length:return So(1),t.map((function(t,r){return{arg:t,index:r,param:e[r]}}));case!0===e[0].variable:So(2);var r=e[0].type;return t.map((function(t,n){return{arg:t,index:n,param:e[n]||{type:r,name:"_"}}}));case t.lengthe.length:So(4);var n=e.length,o=["any"];return t.map((function(t,r){var i=r>=n||!!e[r].optional,a=e[r]||{type:o,name:"_"+r};return{arg:i?Eo(t,a):t,index:r,param:a,optional:i}}));default:throw So(5),new go("Could not understand your arguments and parameter structure!",{args:t,params:e})}}(t,e),i=o.filter((function(t){return!0===t.optional||!0===t.param.optional?function(t){var e=t.arg,r=t.param;return!!Rn(e)&&!(r.type.length>r.type.filter((function(e){return Oo(e,t)})).length)}(t):!(t.param.type.length>t.param.type.filter((function(e){return Oo(e,t)})).length)}));return r?((n={}).error=i,n.data=o.map((function(t){return t.arg})),n):i},Ao=function(t,e){var r,n=Object.keys(t);return r=e,!!n.filter((function(t){return t===r})).length},To=function(t){return!Rn(t)};function xo(t,e){var r=In(e,(function(t,e){return!t[Gn]}));return xr(r,{})?t:function(t,e){var r={};return e=en(e),oe(t,(function(t,n,o){nn(r,e(t,n,o),t)})),r}(t,(function(t,e){return function(t,e,r){var n;return r(t,(function(t,r,o){if(e(t,r,o))return n=r,!1})),n}(r,en((function(t){return t.alias===e})),oe)||e}))}function qo(t,e){return Cn(e,(function(e,r){var n,o;return ot(t[r])||!0===e[Ln]&&To(t[r])?Pn({},e,((n={})[Yn]=!0,n)):((o={})[Kn]=t[r],o[Dn]=e[Dn],o[Ln]=e[Ln]||!1,o[Bn]=e[Bn]||!1,o[Vn]=e[Vn]||!1,o)}))}function Po(t,e){var r=function(t,e){var r=xo(t,e);return{pristineValues:Cn(In(e,(function(t,e){return Ao(r,e)})),(function(t){return t.args})),checkAgainstAppProps:In(e,(function(t,e){return!Ao(r,e)})),config:r}}(t,e),n=r.config,o=r.pristineValues;return[qo(n,r.checkAgainstAppProps),o]}var Co=function(t){return Qn(t)?t:[t]};var $o=function(t,e){return!Qn(e)||function(t,e){return!!t.filter((function(t){return t===e})).length}(e,t)},No=function(t,e){try{return!!ee(e)&&e.apply(null,[t])}catch(t){return!1}};function zo(t){return function(e,r){if(e[Yn])return e[Kn];var n=function(t,e){var r,n=[[t[Kn]],[(r={},r[Dn]=Co(t[Dn]),r[Ln]=t[Ln],r)]];return Reflect.apply(e,null,n)}(e,t);if(n.length)throw So("runValidationAction",r,e),new po(r,n);if(!1!==e[Bn]&&!$o(e[Kn],e[Bn]))throw So(Bn,e[Bn]),new lo(r);if(!1!==e[Vn]&&!No(e[Kn],e[Vn]))throw So(Vn,e[Vn]),new ho(r);return e[Kn]}}function Fo(t,e,r,n){return void 0===t&&(t={}),Pn(function(t,e){var r=t[0],n=t[1],o=Cn(r,zo(e));return Pn(o,n)}(Po(t,e),n),r)}function Io(t,e,r,n,o,l){void 0===r&&(r=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===l&&(l=!1);var p={};return p[c]=t,p[i]=e,!0===r&&(p[a]=!0),Qn(n)&&(p[u]=n),ee(o)&&(p[s]=o),st(l)&&(p[f]=l),p}var Ro=Mn,Jo=Qn,Mo=function(t,e,r){return void 0===r&&(r=!1),new Promise((function(n,o){var i=ko(t,e,r);return r?i.error.length?o(i.error):n(i.data):i.length?o(i):n([])}))},Uo=function(t,e,r){void 0===r&&(r={});var n=r[a],o=r[u],i=r[s],c=r[f];return Io.apply(null,[t,e,n,o,i,c])},Ho=function(t){return function(e,r,n){return void 0===n&&(n={}),Fo(e,r,n,t)}}(ko),Do=function(t,e,r,n){return function(){for(var r=[],o=arguments.length;o--;)r[o]=arguments[o];var i=n.auth[e].params,a=i.map((function(t,e){return r[e]})),u=r[i.length]||{};return Mo(r,i).then((function(){return t.query.apply(t,[e,a,u])})).catch(jo)}};var Lo=Array.isArray,Bo=void 0!==y?y:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},Ko="object"==typeof Bo&&Bo&&Bo.Object===Object&&Bo,Vo="object"==typeof self&&self&&self.Object===Object&&self,Go=(Ko||Vo||Function("return this")()).Symbol,Yo=Object.prototype,Wo=Yo.hasOwnProperty,Qo=Yo.toString,Xo=Go?Go.toStringTag:void 0;var Zo=Object.prototype.toString;var ti="[object Null]",ei="[object Undefined]",ri=Go?Go.toStringTag:void 0;function ni(t){return null==t?void 0===t?ei:ti:ri&&ri in Object(t)?function(t){var e=Wo.call(t,Xo),r=t[Xo];try{t[Xo]=void 0;var n=!0}catch(t){}var o=Qo.call(t);return n&&(e?t[Xo]=r:delete t[Xo]),o}(t):function(t){return Zo.call(t)}(t)}var oi=function(t,e){return function(r){return t(e(r))}}(Object.getPrototypeOf,Object);function ii(t){return null!=t&&"object"==typeof t}var ai="[object Object]",ui=Function.prototype,ci=Object.prototype,si=ui.toString,fi=ci.hasOwnProperty,li=si.call(Object);var pi=Go?Go.prototype:void 0,hi=(pi&&pi.toString,"[object String]");function di(t){return"string"==typeof t||!Lo(t)&&ii(t)&&ni(t)==hi}var vi=function(t,e){return!!t.filter((function(t){return t===e})).length},gi=function(t,e){var r=Object.keys(t);return vi(r,e)},yi=function(){for(var t=arguments,e=[],r=arguments.length;r--;)e[r]=t[r];return e.join("_")},bi=function(t){void 0===t&&(t=!1);var e=Date.now();return t?Math.floor(e/1e3):e},mi="query",_i="mutation",wi="socket",ji="payload",Si="condition",Oi=function(){try{if(window||document)return!0}catch(t){}return!1},Ei=function(){try{if(!Oi()&&Bo)return!0}catch(t){}return!1};var ki=function(t){function e(){for(var r=arguments,n=[],o=arguments.length;o--;)n[o]=r[o];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={name:{configurable:!0}};return r.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,r),e}(function(t){function e(){for(var e=arguments,r=[],n=arguments.length;n--;)r[n]=e[n];t.apply(this,r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.where=function(){return Oi()?"browser":Ei()?"node":"unknown"},e}(Error));var Ai=function(t){var e;return(e={}).args=t,e};var Ti=function(t){return gi(t,"data")&&!gi(t,"error")?t.data:t},xi=function(t){return function(t){if(!ii(t)||ni(t)!=ai)return!1;var e=oi(t);if(null===e)return!0;var r=fi.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&si.call(r)==li}(t)&&(gi(t,mi)||gi(t,_i)||gi(t,wi))},qi=function(t,e){return void 0===e&&(e={}),xi(e)?Promise.resolve(e):t.getContract()},Pi=function(t,e){return function(r){for(var n=[],o=arguments.length-1;o-- >0;)n[o]=arguments[o+1];return new Promise((function(o,i){t.$only(yi(e,r,v),o),t.$only(yi(e,r,g),i),t.$trigger(e,{resolverName:r,args:n})}))}},Ci=function(t,e,r){var n=t.$queues,o=r.debugOn;o&&console.info("(validateRegisteredEvents)","storedEvt",n),n.forEach((function(t){var r=t[0],n=t[1].resolverName;if(o&&console.info("(validateRegisteredEvents)",r,n),!e[r][n])throw new Error(r+"."+n+" not existed in contract!")}))};function $i(t,e,r,n){var i=function(t,e,r,n){var i={query:{},mutation:{}},a=function(e){i.query[e]=function(){for(var r=[],o=arguments.length;o--;)r[o]=arguments[o];var i=n.query[e].params,a=i.map((function(t,e){return r[e]})),u=r[i.length]||{};return Mo(a,i).then((function(){return t.query.apply(t,[e,a,u])})).catch(jo)}};for(var u in n.query)a(u);var c=function(e){i.mutation[e]=function(r,o,i){void 0===i&&(i={});var a=[r,o],u=n.mutation[e].params;return Mo(a,u).then((function(){return t.mutation.apply(t,[e,r,o,i])})).catch(jo)}};for(var s in n.mutation)c(s);if(r.enableAuth&&n.auth){i.auth={};var f=r.loginHandlerName,h=r.logoutHandlerName;n.auth[f]&&(i.auth[f]=function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];var a=Do(t,f,r,n);return a.apply(null,o).then(t.postLoginAction).then((function(t){return e.$trigger(l,t),t}))}),n.auth[h]?i.auth[h]=function(){for(var o=[],i=arguments.length;i--;)o[i]=arguments[i];var a=Do(t,h,r,n);return a.apply(null,o).then(t.postLogoutAction).then((function(t){return e.$trigger(p,t),t}))}:i.auth[h]=function(){t.postLogoutAction(o),e.$trigger(p,o)}}return i}(t,e,r,n);Ci(e,n,r);var a=function(t){e.$only(t,(function(r){var n=r.resolverName,o=r.args;i[t][n]?Reflect.apply(i[t][n],null,o).then((function(r){e.$trigger(yi(t,n,v),r)})).catch((function(r){e.$trigger(yi(t,n,g),r)})):console.error(n+" is not defined in the contract!")}))};for(var u in i)a(u);setTimeout((function(){e.$suspend=!1}),1)}var Ni=function(t,e,r,n){n.$suspend=!0,r.then((function(r){$i(t,n,e,r)}));var o={query:Pi(n,"query"),mutation:Pi(n,"mutation"),auth:Pi(n,"auth"),getToken:function(){return t.rawAuthToken}};return e.exposeContract&&(o.getContract=function(){return t.get()}),e.enableAuth&&(o.userdata=function(){return t.userdata}),o.version="0.1.0",o},zi="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var Fi=Object.assign?Object.assign:function(t,e,r,n){for(var o=arguments,i=1;i=0;e--){var r=oa().key(e);t(ia(r),r)}},remove:function(t){return oa().removeItem(t)},clearAll:function(){return oa().clear()}};function oa(){return ra.localStorage}function ia(t){return oa().getItem(t)}var aa=Mi.trim,ua={name:"cookieStorage",read:function(t){if(!t||!la(t))return null;var e="(?:^|.*;\\s*)"+escape(t).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";return unescape(ca.cookie.replace(new RegExp(e),"$1"))},write:function(t,e){if(!t)return;ca.cookie=escape(t)+"="+escape(e)+"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"},each:sa,remove:fa,clearAll:function(){sa((function(t,e){fa(e)}))}},ca=Mi.Global.document;function sa(t){for(var e=ca.cookie.split(/; ?/g),r=e.length-1;r>=0;r--)if(aa(e[r])){var n=e[r].split("="),o=unescape(n[0]);t(unescape(n[1]),o)}}function fa(t){t&&la(t)&&(ca.cookie=escape(t)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/")}function la(t){return new RegExp("(?:^|;\\s*)"+escape(t).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=").test(ca.cookie)}var pa=function(){var t={};return{defaults:function(e,r){t=r},get:function(e,r){var n=e();return void 0!==n?n:t[r]}}};var ha="expire_mixin",da=function(){var t=this.createStore(this.storage,null,this._namespacePrefix+ha);return{set:function(e,r,n,o){this.hasNamespace(ha)||t.set(r,o);return e()},get:function(t,r){this.hasNamespace(ha)||e.call(this,r);return t()},remove:function(e,r){this.hasNamespace(ha)||t.remove(r);return e()},getExpiration:function(e,r){return t.get(r)},removeExpiredKeys:function(t){var r=[];this.each((function(t,e){r.push(e)}));for(var n=0;n>>8,r[2*n+1]=a%256}return r},decompressFromUint8Array:function(e){if(null==e)return i.decompress(e);for(var r=new Array(e.length/2),n=0,o=r.length;n>=1}else{for(o=1,n=0;n>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[f]}else for(o=a[f],n=0;n>=1;0==--l&&(l=Math.pow(2,h),h++),a[s]=p++,f=String(c)}if(""!==f){if(Object.prototype.hasOwnProperty.call(u,f)){if(f.charCodeAt(0)<256){for(n=0;n>=1}else{for(o=1,n=0;n>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[f]}else for(o=a[f],n=0;n>=1;0==--l&&(l=Math.pow(2,h),h++)}for(o=2,n=0;n>=1;for(;;){if(v<<=1,g==e-1){d.push(r(v));break}g++}return d.join("")},decompress:function(t){return null==t?"":""==t?null:i._decompress(t.length,32768,(function(e){return t.charCodeAt(e)}))},_decompress:function(e,r,n){var o,i,a,u,c,s,f,l=[],p=4,h=4,d=3,v="",g=[],y={val:n(0),position:r,index:1};for(o=0;o<3;o+=1)l[o]=o;for(a=0,c=Math.pow(2,2),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;switch(a){case 0:for(a=0,c=Math.pow(2,8),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;f=t(a);break;case 1:for(a=0,c=Math.pow(2,16),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;f=t(a);break;case 2:return""}for(l[3]=f,i=f,g.push(f);;){if(y.index>e)return"";for(a=0,c=Math.pow(2,d),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;switch(f=a){case 0:for(a=0,c=Math.pow(2,8),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;l[h++]=t(a),f=h-1,p--;break;case 1:for(a=0,c=Math.pow(2,16),s=1;s!=c;)u=y.val&y.position,y.position>>=1,0==y.position&&(y.position=r,y.val=n(y.index++)),a|=(u>0?1:0)*s,s<<=1;l[h++]=t(a),f=h-1,p--;break;case 2:return g.join("")}if(0==p&&(p=Math.pow(2,d),d++),l[f])v=l[f];else{if(f!==h)return null;v=i+i.charAt(0)}g.push(v),l[h++]=i+v.charAt(0),i=v,0==--p&&(p=Math.pow(2,d),d++)}}};return i}();null!=t&&(t.exports=e)}));var ja=[na,ua],Sa=[pa,da,ma,function(){return{get:function(t,e){var r=t(e);if(!r)return r;var n=wa.decompress(r);return null==n?r:this._deserialize(n)},set:function(t,e,r){var n=wa.compress(this._serialize(r));t(e,n)}}}],Oa=Zi.createStore(ja,Sa),Ea=Mi.Global;function ka(){return Ea.sessionStorage}function Aa(t){return ka().getItem(t)}var Ta=[{name:"sessionStorage",read:Aa,write:function(t,e){return ka().setItem(t,e)},each:function(t){for(var e=ka().length-1;e>=0;e--){var r=ka().key(e);t(Aa(r),r)}},remove:function(t){return ka().removeItem(t)},clearAll:function(){return ka().clear()}},ua],xa=[pa,da],qa=Zi.createStore(Ta,xa),Pa=Oa,Ca=qa,$a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function Na(t){this.message=t}Na.prototype=new Error,Na.prototype.name="InvalidCharacterError";var za="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new Na("'atob' failed: The string to be decoded is not correctly encoded.");for(var r,n,o=0,i=0,a="";n=e.charAt(i++);~n&&(r=o%4?64*r+n:n,o++%4)?a+=String.fromCharCode(255&r>>(-2*o&6)):0)n=$a.indexOf(n);return a};var Fa=function(t){var e=t.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(za(t).replace(/(.)/g,(function(t,e){var r=e.charCodeAt(0).toString(16).toUpperCase();return r.length<2&&(r="0"+r),"%"+r})))}(e)}catch(t){return za(e)}};function Ia(t){this.message=t}Ia.prototype=new Error,Ia.prototype.name="InvalidTokenError";var Ra=function(t,e){if("string"!=typeof t)throw new Ia("Invalid token specified");var r=!0===(e=e||{}).header?0:1;try{return JSON.parse(Fa(t.split(".")[r]))}catch(t){throw new Ia("Invalid token specified: "+t.message)}},Ja=Ia;Ra.InvalidTokenError=Ja;var Ma,Ua,Ha,Da,La,Ba,Ka,Va,Ga,Ya,Wa,Qa=function(t){void 0===t&&(t=!1);var e=Date.now();return t?Math.floor(e/1e3):e},Xa=y.performance||{};Xa.now||Xa.mozNow||Xa.msNow||Xa.oNow||Xa.webkitNow,Ma="koa",void 0===(Ua="jsonql-utils")&&(Ua="jsonql"),t(Ua).extend(Ma);function Za(t){if(Ro(t))return function(t){var e=t.iat||Qa();if(t.exp&&e>=t.exp){var r=new Date(t.exp).toISOString();throw new go("Token has expired on "+r,t)}return t}(Ra(t));throw new go("Token must be a string!")}Uo("HS256",["string"]),Uo(!1,["boolean","number","string"],((Ha={})[f]="exp",Ha[a]=!0,Ha)),Uo(!1,["boolean","number","string"],((Da={})[f]="nbf",Da[a]=!0,Da)),Uo(!1,["boolean","string"],((La={})[f]="iss",La[a]=!0,La)),Uo(!1,["boolean","string"],((Ba={})[f]="sub",Ba[a]=!0,Ba)),Uo(!1,["boolean","string"],((Ka={})[f]="iss",Ka[a]=!0,Ka)),Uo(!1,["boolean"],((Va={})[a]=!0,Va)),Uo(!1,["boolean","string"],((Ga={})[a]=!0,Ga)),Uo(!1,["boolean","string"],((Ya={})[a]=!0,Ya)),Uo(!1,["boolean"],((Wa={})[a]=!0,Wa));var tu=n[0],eu=n[1],ru=function(t){!function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];try{window&&window.console&&Reflect.apply(console.log,null,t)}catch(t){}}(t),this.fly=t.Fly?new t.Fly:new Fly,this.opts=t,this.extraHeader={},this.extraParams={},this.reqInterceptor(),this.resInterceptor()},nu={headers:{configurable:!0}};nu.headers.set=function(t){this.extraHeader=t},ru.prototype.request=function(t,e,r){var n;void 0===e&&(e={}),void 0===r&&(r={}),this.headers=r;var o=Pn({},{_cb:bi()},this.extraParams);if(this.opts.enableJsonp){var i=function(t){return Object.keys(t)[0]}(t);o=Pn({},o,((n={}).jsonqlJsonpCallback=i,n)),t=t[i]}return this.fly.request(this.jsonqlEndpoint,t,Pn({},{method:tu,params:o},e))},ru.prototype.reqInterceptor=function(){var t=this;this.fly.interceptors.request.use((function(e){var r=t.getHeaders();for(var n in t.log("request interceptor call",r),r)e.headers[n]=r[n];return e}))},ru.prototype.processJsonp=function(t){return Ti(t)},ru.prototype.resInterceptor=function(){var t=this,e=this,r=e.opts.enableJsonp;this.fly.interceptors.response.use((function(n){t.log("response interceptor call"),e.cleanUp();var o=Ro(n.data)?JSON.parse(n.data):n.data;return r?e.processJsonp(o):Ti(o)}),(function(t){throw e.cleanUp(),console.error(t),new yo("Server side error",t)}))},ru.prototype.getHeaders=function(){return this.opts.enableAuth?Pn({},r,this.getAuthHeader(),this.extraHeader):Pn({},r,this.extraHeader)},ru.prototype.cleanUp=function(){this.extraHeader={},this.extraParams={}},ru.prototype.get=function(){var t=this;return this.opts.showContractDesc&&(this.extraParams=Pn({},this.extraParams,h)),this.request({},{method:"GET"},this.contractHeader).then(wo).then((function(e){return t.log("get contract result",e),e.cache&&e.contract?e.contract:e}))},ru.prototype.query=function(t,e){return void 0===e&&(e=[]),this.request(function(t,e,r){var n;if(void 0===e&&(e=[]),void 0===r&&(r=!1),di(t)&&Lo(e)){var o=Ai(e);return!0===r?o:((n={})[t]=o,n)}throw new ki("[createQuery] expect resolverName to be string and args to be array!",{resolverName:t,args:e})}(t,e)).then(wo)},ru.prototype.mutation=function(t,e,r){return void 0===e&&(e={}),void 0===r&&(r={}),this.request(function(t,e,r,n){var o;void 0===r&&(r={}),void 0===n&&(n=!1);var i={};if(i[ji]=e,i[Si]=r,!0===n)return i;if(di(t))return(o={})[t]=i,o;throw new ki("[createMutation] expect resolverName to be string!",{resolverName:t,payload:e,condition:r})}(t,e,r),{method:eu}).then(wo)},Object.defineProperties(ru.prototype,nu);var ou=function(t){function e(e,r){void 0===r&&(r=null),r&&(e.Fly=r),t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={storeIt:{configurable:!0},jsonqlEndpoint:{configurable:!0},jsonqlContract:{configurable:!0},jsonqlToken:{configurable:!0},jsonqlUserdata:{configurable:!0}};return r.storeIt.set=function(t){throw console.info("storeIt",t),Jo(t)&&t.length>=2&&Reflect.apply(Pa.set,Pa,t),new vo("Expect argument to be array and least 2 items!")},r.jsonqlEndpoint.set=function(t){var e=Pa.get("endpoint")||[];vi(e,t)||(e.push(t),this.storeId=["endpoint",e],this.endpointIndex=e.length-1)},r.jsonqlContract.set=function(t){var e=this.opts.storageKey,r=[e],n=t[0],o=t[1],i=Pa.get(e)||[];i[this.endpointIndex||0]=n,r.push(i),o&&r.push(o),this.opts.keepContract&&(this.storeIt=r)},r.jsonqlToken.set=function(t){var e="credential",r=localStorage.get(e)||[];if(!vi(r,t)){var n=r.length-1;r[n]=t,this[e+"Index"]=n;var o=[e,r];if(this.opts.tokenExpired){var i=parseFloat(this.opts.tokenExpired);if(!isNaN(i)&&i>0){var a=bi();o.push(a+parseFloat(i))}}return this.storeIt=o,this.jsonqlUserdata=this.decoder(t),t}return!1},r.jsonqlUserdata.set=function(t){var e=["userdata",t];return t.exp&&e.push(t.exp),Reflect.apply(Pa.set,Pa,e)},r.jsonqlEndpoint.get=function(){var t=Pa.get("endpoint");if(!t){var e=this.opts,r=[e.hostname,e.jsonqlPath].join("/");return this.jsonqlEndpoint=r,r}return t[this.endpointIndex]},r.jsonqlContract.get=function(){var t=this.opts.storageKey;return(Pa.get(t)||[])[this.endpointIndex]||!1},r.jsonqlToken.get=function(){var t="credential",e=localStorage.get(t);return!!e&&e[this[t+"Index"]]},r.jsonqlUserdata.get=function(){return Ca.get("userdata")},e.prototype.log=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];!0===this.opts.debugOn&&Reflect.apply(console.info,console,t)},Object.defineProperties(e.prototype,r),e}(function(t){function e(e){t.call(this,e),e.enableAuth&&e.useJwt&&(this.setDecoder=Za)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={userdata:{configurable:!0},rawAuthToken:{configurable:!0},setDecoder:{configurable:!0}};return r.userdata.get=function(){return this.jsonqlUserdata},r.rawAuthToken.get=function(){return this.jsonqlToken},r.setDecoder.set=function(t){"function"==typeof t&&(this.decoder=t)},e.prototype.storeToken=function(t){return this.jsonqlToken=t},e.prototype.decoder=function(t){return t},e.prototype.getAuthHeader=function(){var t,e=this.rawAuthToken;return e?((t={})[this.opts.AUTH_HEADER]="Bearer "+e,t):{}},Object.defineProperties(e.prototype,r),e}(function(t){function e(e){t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={contractHeader:{configurable:!0}};return e.prototype.getContract=function(){var t=this.readContract();if(this.log("getContract first call",t),t&&Array.isArray(t)){var e=t[this.endpointIndex||0];if(e)return Promise.resolve(e)}return this.get().then(this.storeContract.bind(this))},r.contractHeader.get=function(){var t={};return!1!==this.opts.contractKey&&(t[this.opts.contractKeyName]=this.opts.contractKey),t},e.prototype.storeContract=function(t){if(!xi(t))throw new vo("Contract is malformed!");var e=[t];if(this.opts.contractExpired){var r=parseFloat(this.opts.contractExpired);!isNaN(r)&&r>0&&e.push(r)}return this.jsonqlContract=e,this.log("storeContract return result",t),t},e.prototype.readContract=function(){return xi(this.opts.contract)?this.opts.contract:Pa.get(this.opts.storageKey)},Object.defineProperties(e.prototype,r),e}(ru))),iu={contract:!1,MUTATION_ARGS:["name","payload","conditions"],CONTENT_TYPE:e,BEARER:"Bearer",AUTH_HEADER:"Authorization"},au={hostname:Uo([window.location.protocol,window.location.host].join("//"),["string"]),jsonqlPath:Uo("jsonql",["string"]),loginHandlerName:Uo(l,["string"]),logoutHandlerName:Uo(p,["string"]),enableJsonp:Uo(!1,["boolean"]),enableAuth:Uo(!1,["boolean"]),useJwt:Uo(!0,["boolean"]),useLocalstorage:Uo(!0,["boolean"]),storageKey:Uo("storageKey",["string"]),authKey:Uo("authKey",["string"]),contractExpired:Uo(0,["number"]),keepContract:Uo(!0,["boolean"]),exposeContract:Uo(!1,["boolean"]),showContractDesc:Uo(!1,["boolean"]),contractKey:Uo(!1,["boolean"]),contractKeyName:Uo("X-JSONQL-CV-KEY",["string"]),enableTimeout:Uo(!1,["boolean"]),timeout:Uo(5e3,["number"]),returnInstance:Uo(!1,["boolean"]),allowReturnRawToken:Uo(!1,["boolean"]),debugOn:Uo(!1,["boolean"])};var uu=new WeakMap,cu=new WeakMap;var su=function(){this.__suspend__=null,this.queueStore=new Set},fu={$suspend:{configurable:!0},$queues:{configurable:!0}};fu.$suspend.set=function(t){var e=this;if("boolean"!=typeof t)throw new Error("$suspend only accept Boolean value!");var r=this.__suspend__;this.__suspend__=t,this.logger("($suspend)","Change from "+r+" --\x3e "+t),!0===r&&!1===t&&setTimeout((function(){e.release()}),1)},su.prototype.$queue=function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];return!0===this.__suspend__&&(this.logger("($queue)","added to $queue",t),this.queueStore.add(t)),this.__suspend__},fu.$queues.get=function(){var t=this.queueStore.size;return this.logger("($queues)","size: "+t),t>0?Array.from(this.queueStore):[]},su.prototype.release=function(){var t=this,e=this.queueStore.size;if(this.logger("(release)","Release was called "+e),e>0){var r=Array.from(this.queueStore);this.queueStore.clear(),this.logger("queue",r),r.forEach((function(e){t.logger(e),Reflect.apply(t.$trigger,t,e)})),this.logger("Release size "+this.queueStore.size)}},Object.defineProperties(su.prototype,fu);var lu=function(t){function e(e){void 0===e&&(e={}),t.call(this,e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var r={$done:{configurable:!0}};return e.prototype.logger=function(){},e.prototype.$on=function(t,e,r){var n=this;void 0===r&&(r=null);this.validate(t,e);var o=this.takeFromStore(t);if(!1===o)return this.logger("($on)",t+" callback is not in lazy store"),this.addToNormalStore(t,"on",e,r);this.logger("($on)",t+" found in lazy store");var i=0;return o.forEach((function(o){var a=o[0],u=o[1],c=o[2];if(c&&"on"!==c)throw new Error("You are trying to register an event already been taken by other type: "+c);n.run(e,a,r||u),i+=n.addToNormalStore(t,"on",e,r||u)})),i},e.prototype.$once=function(t,e,r){void 0===r&&(r=null),this.validate(t,e);var n=this.takeFromStore(t);this.normalStore;if(!1===n)return this.logger("($once)",t+" not in the lazy store"),this.addToNormalStore(t,"once",e,r);this.logger("($once)",n);var o=Array.from(n)[0],i=o[0],a=o[1],u=o[2];if(u&&"once"!==u)throw new Error("You are trying to register an event already been taken by other type: "+u);this.run(e,i,r||a),this.$off(t)},e.prototype.$only=function(t,e,r){var n=this;void 0===r&&(r=null),this.validate(t,e);var o=!1,i=this.takeFromStore(t);(this.normalStore.has(t)||(this.logger("($only)",t+" add to store"),o=this.addToNormalStore(t,"only",e,r)),!1!==i)&&(this.logger("($only)",t+" found data in lazy store to execute"),Array.from(i).forEach((function(t){var o=t[0],i=t[1],a=t[2];if(a&&"only"!==a)throw new Error("You are trying to register an event already been taken by other type: "+a);n.run(e,o,r||i)})));return o},e.prototype.$onlyOnce=function(t,e,r){void 0===r&&(r=null),this.validate(t,e);var n=!1,o=this.takeFromStore(t);if(this.normalStore.has(t)||(this.logger("($onlyOnce)",t+" add to store"),n=this.addToNormalStore(t,"onlyOnce",e,r)),!1!==o){this.logger("($onlyOnce)",o);var i=Array.from(o)[0],a=i[0],u=i[1],c=i[2];if(c&&"onlyOnce"!==c)throw new Error("You are trying to register an event already been taken by other type: "+c);this.run(e,a,r||u),this.$off(t)}return n},e.prototype.$replace=function(t,e,r,n){if(void 0===r&&(r=null),void 0===n&&(n="on"),this.validateType(n)){this.$off(t);var o=this["$"+n];return Reflect.apply(o,this,[t,e,r])}throw new Error(n+" is not supported!")},e.prototype.$trigger=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1),this.validateEvt(t);var o=0,i=this.normalStore;if(this.logger("($trigger)","normalStore",i),i.has(t)){var a=this.$queue(t,e,r,n);if(this.logger("($trigger)",t,"found; add to queue: ",a),!0===a)return!1;for(var u=Array.from(i.get(t)),c=u.length,s=!1,f=0;f0;)n[o]=arguments[o+2];if(t.has(e)?(this.logger("(addToStore)",e+" existed"),r=t.get(e)):(this.logger("(addToStore)","create new Set for "+e),r=new Set),n.length>2)if(Array.isArray(n[0])){var i=n[2];this.checkTypeInLazyStore(e,i)||r.add(n)}else this.checkContentExist(n,r)||(this.logger("(addToStore)","insert new",n),r.add(n));else r.add(n);return t.set(e,r),[t,r.size]},e.prototype.checkContentExist=function(t,e){return!!Array.from(e).filter((function(e){return e[0]===t[0]})).length},e.prototype.checkTypeInStore=function(t,e){this.validateEvt(t,e);var r=this.$get(t,!0);return!1===r||!r.filter((function(t){var r=t[3];return e!==r})).length},e.prototype.checkTypeInLazyStore=function(t,e){this.validateEvt(t,e);var r=this.lazyStore.get(t);return this.logger("(checkTypeInLazyStore)",r),!!r&&!!Array.from(r).filter((function(t){return t[2]!==e})).length},e.prototype.addToNormalStore=function(t,e,r,n){if(void 0===n&&(n=null),this.logger("(addToNormalStore)",t,e,"try to add to normal store"),this.checkTypeInStore(t,e)){this.logger("(addToNormalStore)",e+" can add to "+t+" normal store");var o=this.hashFnToKey(r),i=[this.normalStore,t,o,r,n,e],a=Reflect.apply(this.addToStore,this,i),u=a[0],c=a[1];return this.normalStore=u,c}return!1},e.prototype.addToLazyStore=function(t,e,r,n){void 0===e&&(e=[]),void 0===r&&(r=null),void 0===n&&(n=!1);var o=[this.lazyStore,t,this.toArray(e),r];n&&o.push(n);var i=Reflect.apply(this.addToStore,this,o),a=i[0],u=i[1];return this.lazyStore=a,u},e.prototype.toArray=function(t){return Array.isArray(t)?t:[t]},r.normalStore.set=function(t){uu.set(this,t)},r.normalStore.get=function(){return uu.get(this)},r.lazyStore.set=function(t){cu.set(this,t)},r.lazyStore.get=function(){return cu.get(this)},e.prototype.hashFnToKey=function(t){return t.toString().split("").reduce((function(t,e){return(t=(t<<5)-t+e.charCodeAt(0))&t}),0)+""},Object.defineProperties(e.prototype,r),e}(su));return function(t,e){void 0===e&&(e={});var r,n=e.contract,o=function(t){return Ho(t,au,iu)}(e),i=new ou(o,t),a=qi(i,n),u=(r=o.debugOn,new lu({logger:r?function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];t.unshift("[NBS]"),console.log.apply(null,t)}:void 0})),c=Ni(i,o,a,u);return c.eventEmitter=u,c}})); +//# sourceMappingURL=static.js.map diff --git a/packages/@jsonql/client/static.js.map b/packages/@jsonql/client/static.js.map new file mode 100644 index 0000000000000000000000000000000000000000..80475c921c464da0243f229d957d3b9a0968b0b0 --- /dev/null +++ b/packages/@jsonql/client/static.js.map @@ -0,0 +1 @@ +{"version":3,"file":"static.js","sources":["node_modules/store/plugins/defaults.js","node_modules/store/plugins/expire.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i { + let obj = list.map(l => ( + { [l[0]]: [ l[1] ] } + )) + .reduce((first, next) => { + return Object.assign(first, next) + }, {}) + + console.info(obj) + + t.pass() + +}) diff --git a/packages/@jsonql/client/tests/fixtures/contract.js b/packages/@jsonql/client/tests/fixtures/contract.js new file mode 100644 index 0000000000000000000000000000000000000000..d1098c19df8f070037deec26430767108b9ca859 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/contract.js @@ -0,0 +1,9 @@ +const contractApi = require('../../../contract-cli'); +const { join } = require('path'); + +contractApi({ + inDir: join(__dirname, 'resolvers'), + outDir: join(__dirname, 'contracts', 'tmp'), + useDoc: true, + logDirectory: join(__dirname, '..','..' , '..', 'contract-cli','tests','fixtures' ,'tmp', 'contracts', 'logs') +}); diff --git a/packages/@jsonql/client/tests/fixtures/dev.js b/packages/@jsonql/client/tests/fixtures/dev.js new file mode 100644 index 0000000000000000000000000000000000000000..f819c8e1c5b4992fe38ab56e98fb0dfd94d1c953 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/dev.js @@ -0,0 +1,56 @@ +// this is for doing test on separate modules +var ctn = 0; +$(function() { + var url = '/jsonql'; + console.info('calling dev') + + fly.interceptors.request.use(function(request) { + console.info(++ctn, 'request', request) + request.headers['Accept'] = 'application/vnd.api+json'; + request.headers['Content-Type'] = 'application/vnd.api+json;charset=utf-8'; + + if (ctn > 1) { + console.info('add another header') + request.headers['x-dummy-header'] = 'whatver'; + } + return request; + }) + + fly.interceptors.response.use( + function(response) { + console.info('response', typeof response, response) + var result = typeof response.data === 'object' ? response.data : JSON.parse(response.data) + // console.info('result', result) + if (result.error) { + throw new Error('WTF?', result.error) + } + return result + } + ) + + var payload = { + testList: { + args: [] + } + } + + fly.post(url, payload) + .then(function(res) { + console.info('response',typeof res.data, res.data) + }) + /* + fly.put('/test', payload) + .then(function(res) { + console.info('PUT done') + }) + */ + ++ctn; + fly.post(url, {alwaysAvailable: {args: []}}) + .then(function(res) { + console.info('success', res.data.data) + }) + .catch(function(err) { + console.error('catch error', err) + }) + +}) diff --git a/packages/@jsonql/client/tests/fixtures/favicon.ico b/packages/@jsonql/client/tests/fixtures/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8dbd70bc3f8b3b098330e6bd7a3f602864f63d67 Binary files /dev/null and b/packages/@jsonql/client/tests/fixtures/favicon.ico differ diff --git a/packages/@jsonql/client/tests/fixtures/helpers/setup-browser.js b/packages/@jsonql/client/tests/fixtures/helpers/setup-browser.js new file mode 100644 index 0000000000000000000000000000000000000000..8e6e1dfead05e44f92de7c1675cf300fe657ca7d --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/helpers/setup-browser.js @@ -0,0 +1,2 @@ +const browserEnv = require('browser-env'); +browserEnv(['window', 'document', 'navigator']); diff --git a/packages/@jsonql/client/tests/fixtures/index.html b/packages/@jsonql/client/tests/fixtures/index.html new file mode 100644 index 0000000000000000000000000000000000000000..d593517c069b14019c3d17fe7ff331a7830c67ee --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/index.html @@ -0,0 +1,104 @@ + + + + @jsonql/client dev page + + + + +
+

Wait ...

+
+ +
+ +
+
+
result ...
+ +
+
+ + +
+ +
+ +
+
+ + + + + + + + + + + diff --git a/packages/@jsonql/client/tests/fixtures/keys/privateKey.pem b/packages/@jsonql/client/tests/fixtures/keys/privateKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..30c1dd37106294cddb15b5083f665560add2d691 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/keys/privateKey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCZKoYQuCTxzHXVydqSXYwcc+o/x7Cn7BRVAnlM1W6f4darRnjd +EoWSK7OGhmuIgQ4gpes1lQO7qk31w7EGTNbODTOg7brrnjCsU1EMPemAQPisiLZe +0t4TyDwP1SwmSu46oKJrabanrUHA2ulfVjh02Dr1GXWnABXF16seO11vAwIDAQAB +AoGBAIXzVYobsVuyJz+QJ9Inc9iSW0PqPQmugl2SK0lRw0yaMqZZnGwivaQHChtV +RYf87cEJufmDV99w4ntT6GaNHrF9Cvyq+c+ZpY0IE4cPzHY5d5er6Ak047714F/a +t55LCcTFMJR/Y+/Z+mOEa8Va9MR1JrrYbuq2GUyL3EeVyfuRAkEAy0uRPL+0k0Tc +dZvhM+HG3KbPBQl4tnqRJ9mu7pwa2LegKDqw+6sNJMcANxVVwI5FKzShm4j2/5F0 +iK+w4z3E+QJBAMDf9K/QOxrskXl8IBFhOGFpsrojJCWl5/cUE6R0qQgmhAj6C3G1 +3gOZRk+jGBNIBexIllwcAojl9lsGU/Xm3tsCQQDDHYADwirZvZmp9zYpyWRHmoHO +38xPt0th5/eRY5oQrgy1D7+VjBJNXgHC3GM1MFcKpLUGxmnp1/z0w0sOjtZhAkAb +Rc/AqI4jAX6UkhOqwXeKdrq6DUwIMsx5KJKad5CLQX78EfdaTeAl3B+QFTzLRSzp +O15fiepl1zadqmhm5g1vAkAZJHu7iSE1hKaTRfR1/VJDRrJLOz3MRyckgr7RUSSz +CH5ua1QEpRvos4klIUXNHoOAAkk3rO1GCJOk0cieTdum +-----END RSA PRIVATE KEY----- diff --git a/packages/@jsonql/client/tests/fixtures/keys/publicKey.pem b/packages/@jsonql/client/tests/fixtures/keys/publicKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..b741f2f9b8e27816fef2c0be3efd2acbc57252a5 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/keys/publicKey.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZKoYQuCTxzHXVydqSXYwcc+o/ +x7Cn7BRVAnlM1W6f4darRnjdEoWSK7OGhmuIgQ4gpes1lQO7qk31w7EGTNbODTOg +7brrnjCsU1EMPemAQPisiLZe0t4TyDwP1SwmSu46oKJrabanrUHA2ulfVjh02Dr1 +GXWnABXF16seO11vAwIDAQAB +-----END PUBLIC KEY----- diff --git a/packages/@jsonql/client/tests/fixtures/obj.js b/packages/@jsonql/client/tests/fixtures/obj.js new file mode 100644 index 0000000000000000000000000000000000000000..7aa057f9a31d52117839e823573de61fdcc2bdf8 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/obj.js @@ -0,0 +1,19 @@ +// this is testing some of the theory + +const obj = {}; + +const fn = () => { + console.info('Should call somebody else'); +} + + +Object.defineProperty(obj, 'key', { + get() { + return obj.key; + } + set(newValue) { + obj.key = newValue; + }, + enumerable: true, + configurable: true +}); diff --git a/packages/@jsonql/client/tests/fixtures/old-builds/rollup.example.js b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.example.js new file mode 100644 index 0000000000000000000000000000000000000000..59fbbb9c858ecb9561d272fb0cad605f56dfe356 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.example.js @@ -0,0 +1,76 @@ +/** + * Rollup config from jsonql-params-validator that build everything correctly + * so why this one doesn't work? + */ +import { join } from 'path'; +import buble from 'rollup-plugin-buble'; +import { uglify } from 'rollup-plugin-uglify'; + +import replace from 'rollup-plugin-replace'; +import commonjs from 'rollup-plugin-commonjs'; + +import json from 'rollup-plugin-json'; + +import nodeResolve from 'rollup-plugin-node-resolve'; +import nodeGlobals from 'rollup-plugin-node-globals'; +import builtins from 'rollup-plugin-node-builtins'; +import size from 'rollup-plugin-bundle-size'; +// support async functions +import async from 'rollup-plugin-async'; +// get the version info +import { version } from './package.json'; + +const env = process.env.NODE_ENV; + +let plugins = [ + json({ + preferConst: true + }), + buble({ + objectAssign: 'Object.assign' + }), + nodeResolve({ + preferBuiltins: true, + mainFields: ['module', 'browser'] + }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + builtins(), + async(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + '__PLACEHOLDER__': `version: ${version} module: ${env==='prod' ? 'cjs' : 'umd'}` + }), + uglify(), + size() +]; + +const file = env === 'prod' ? 'jsonql-params-validator.cjs.js' : 'jsonql-params-validator.umd.js'; + +console.log('outfile is %s', file); + +let config = { + input: join(__dirname, 'index.js'), + output: { + name: 'jsonqlParamsValidator', + file: join(__dirname, 'dist', file), + format: env === 'prod' ? 'cjs' : 'umd', + sourcemap: true, + globals: { + 'promise-polyfill': 'Promise', + 'debug': 'debug', + 'fs': 'fs', + 'util': 'util' + } + }, + external: [ + 'debug', + 'Promise', + 'promise-polyfill' + ], + plugins: plugins +}; + +export default config; diff --git a/packages/@jsonql/client/tests/fixtures/old-builds/rollup.full.config.js b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.full.config.js new file mode 100644 index 0000000000000000000000000000000000000000..1aa67008594d906744358aa5f7f17b6c56207255 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.full.config.js @@ -0,0 +1,109 @@ +/** + * Rollup config to create a full distribution with fly.js for browser + */ +import { join } from 'path' +import buble from 'rollup-plugin-buble' +import { terser } from "rollup-plugin-terser" +import replace from 'rollup-plugin-replace' +import commonjs from 'rollup-plugin-commonjs' +import nodeResolve from 'rollup-plugin-node-resolve' +import nodeGlobals from 'rollup-plugin-node-globals' +// import builtins from 'rollup-plugin-node-builtins' +import size from 'rollup-plugin-bundle-size' +import async from 'rollup-plugin-async' + +import pkg from './package.json' +/* + need to include more different one + ws: + ap: + node: flyio/src/node + weex: +*/ +const getReplace = () => { + switch (process.env.TARGET) { + case 'wx': + return 'flyio/dist/npm/wx' + case 'ap': + return 'flyio/dist/npm/ap' + case 'weex': + return 'flyio/dist/npm/weex' + default: // browser + return 'flyio/dist/npm/fly' + } +} + +const getOutputFile = () => { + let fileName = env === 'production' ? 'jsonql-client.umd.js' : 'jsonql-static-client.umd.js' + switch (process.env.TARGET) { + case 'wx': + return join(__dirname, 'wx.js') + case 'ap': + return join(__dirname, 'ap.js') + case 'weex': + return join(__dirname, 'weex.js') + default: + return join(__dirname, 'dist', fileName) + } +} + +const env = process.env.NODE_ENV; + +let plugins = [ + buble({ + objectAssign: 'Object.assign' + }), + nodeResolve({ + preferBuiltins: true + }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + // builtins(), + async(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + '__VERSION__': pkg.version, + '__TO_REPLACE_IMPORT__': getReplace() + }) +] + +// plugins.push(terser()) +plugins.push(size()) + +let globals = { + debug: 'debug', + 'promise-polyfill': 'Promise', + 'fs': 'fs', + 'util': 'util', + 'path': 'path' +} +let external = [ + 'debug', + 'fetch', + 'Promise', + 'promise-polyfill', + 'superagent', + 'handlebars', + 'tty', + 'fs', + 'util' +] + +let sourceFile = env === 'production' ? 'full.js' : join('src', 'static-full.js') +let moduleName = env === 'production' ? 'jsonqlClient' : 'jsonqlClientStatic' +let config = { + input: join(__dirname, sourceFile), + output: [{ + name: moduleName, + file: getOutputFile(), + format: 'umd', + sourcemap: true, + globals + }], + plugins, + external +} + +export default config diff --git a/packages/@jsonql/client/tests/fixtures/old-builds/rollup.test.config.js b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.test.config.js new file mode 100644 index 0000000000000000000000000000000000000000..78a778497e806155184cac6f16fc9c73f2822644 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/old-builds/rollup.test.config.js @@ -0,0 +1,71 @@ +/** + * Rollup config for TESTING + * DO NOT USE THIS DIRECTLY + */ +import { join } from 'path' +import buble from 'rollup-plugin-buble' +import replace from 'rollup-plugin-replace' +import commonjs from 'rollup-plugin-commonjs' +import size from 'rollup-plugin-bundle-size' +import nodeResolve from 'rollup-plugin-node-resolve' +import nodeGlobals from 'rollup-plugin-node-globals' +import builtins from 'rollup-plugin-node-builtins'; +import async from 'rollup-plugin-async' + +const env = process.env.NODE_ENV; + +let plugins = [ + buble({ + objectAssign: 'Object.assign' + }), + nodeResolve({ preferBuiltins: false }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + builtins(), + async(), + replace({ 'process.env.NODE_ENV': JSON.stringify('production') }), + size() +] + +const dist = join(__dirname, 'dist') +let in_file = join(__dirname, 'test.js') +let out_file = join(dist, 'jsonql-client.test.js') +let name = 'JsonqlClientOOP'; +// swith the files using the env +switch (env) { + case 'stores': + in_file = join(src, 'lib', 'stores', 'index.js') + out_file = join(dist, 'jsonql-stores.js') + name = 'JsonqlStores'; + break; + default: + // nothing +} + +let config = { + input: in_file, + output: { + name: name, + file: out_file, + format: 'umd', + sourcemap: true, + globals: { + debug: 'debug', + 'promise-polyfill': 'Promise' + } + }, + external: [ + 'debug', + 'fetch', + 'Promise', + 'promise-polyfill', + 'superagent', + 'handlebars', + 'tty' + ], + plugins: plugins +} + +export default config diff --git a/packages/@jsonql/client/tests/fixtures/options.json b/packages/@jsonql/client/tests/fixtures/options.json new file mode 100644 index 0000000000000000000000000000000000000000..aaf14c589ce8487b60b920d02dc2057cec01193a --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/options.json @@ -0,0 +1,8 @@ +{ + "server": { + "port": 7890 + }, + "auth": { + "contractKey": "92349839843098324" + } +} diff --git a/packages/@jsonql/client/tests/fixtures/resolvers/auth/issuer.js b/packages/@jsonql/client/tests/fixtures/resolvers/auth/issuer.js new file mode 100644 index 0000000000000000000000000000000000000000..609c29661d8211ec41c5848abfd28a692a04ecc5 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/resolvers/auth/issuer.js @@ -0,0 +1,10 @@ +const debug = require('debug')('jsonql-client:auth:issuer'); + +/** + * @param {string} key for append + * @return {string} concat string + */ +module.exports = function(key) { + debug('got a key', key); + return 123456 + key; +} diff --git a/packages/@jsonql/client/tests/fixtures/resolvers/auth/validator.js b/packages/@jsonql/client/tests/fixtures/resolvers/auth/validator.js new file mode 100644 index 0000000000000000000000000000000000000000..ab17b33b3d8e7785db3e7b0836453bd1e8369c55 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/resolvers/auth/validator.js @@ -0,0 +1,16 @@ +const debug = require('debug')('jsonql-client:auth:validator'); + +/** + * @param {string} key for validation + * @return {boolean} true on success + */ +module.exports = function(key) { + debug('got a key', key) + return true; + /* + if (key) { + return key.substr(0, 3) === '123'; + } + return false; + */ +} diff --git a/packages/@jsonql/client/tests/fixtures/resolvers/mutation/plus.js b/packages/@jsonql/client/tests/fixtures/resolvers/mutation/plus.js new file mode 100644 index 0000000000000000000000000000000000000000..fce66a5dbf17615b0e6cd2d2f6994b32c5907704 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/resolvers/mutation/plus.js @@ -0,0 +1,15 @@ +const debug = require('debug')('jsonql-client:mutation:plus'); + +/** + * @param {object} payload the payload object + * @param {string} payload.a required key a + * @param {string} payload.b required key b + * @param {object} [conditions={}] optional + * @return {string} concat string of a + b; + */ +module.exports = function(payload, conditions = {}) { + debug('mutation.plus called', payload); + const result = payload.a + payload.b; + debug('result is', result); + return result; +} diff --git a/packages/@jsonql/client/tests/fixtures/resolvers/query/get-something.js b/packages/@jsonql/client/tests/fixtures/resolvers/query/get-something.js new file mode 100644 index 0000000000000000000000000000000000000000..e0f0e4d1cadca3d6281cc84607f0999b4e0d2dee --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/resolvers/query/get-something.js @@ -0,0 +1,12 @@ + +/** + * This is a new query that require parameters for testing + * @param {string} key key + * @param {string} [value='world'] optional value + * @return {object} put key / value together into an object + */ +module.exports = function(key, value = 'world') { + return { + [key]: value + } +} diff --git a/packages/@jsonql/client/tests/fixtures/resolvers/query/test-list.js b/packages/@jsonql/client/tests/fixtures/resolvers/query/test-list.js new file mode 100644 index 0000000000000000000000000000000000000000..1af62f209a2dd3f6f81c3da047bf91f12792c5bc --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/resolvers/query/test-list.js @@ -0,0 +1,9 @@ +/** + * Just return a Hello world object + * @return {object} key hello prop world + */ +module.exports = async function() { + return { + hello: 'World!' + }; +} diff --git a/packages/@jsonql/client/tests/fixtures/run.js b/packages/@jsonql/client/tests/fixtures/run.js new file mode 100644 index 0000000000000000000000000000000000000000..d474b919ade224272ef713b5ed95f0718e42596e --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/run.js @@ -0,0 +1,3 @@ +const server = require('./server'); + +server(); diff --git a/packages/@jsonql/client/tests/fixtures/server.js b/packages/@jsonql/client/tests/fixtures/server.js new file mode 100644 index 0000000000000000000000000000000000000000..1e8f9729d0d9579aa751762864bf64d347226827 --- /dev/null +++ b/packages/@jsonql/client/tests/fixtures/server.js @@ -0,0 +1,46 @@ +const { join } = require('path') +const options = require('./options.json') +const favicon = require('koa-favicon') +const serverIoCore = require('server-io-core') +const jsonqlKoa = require('@jsonql/koa') +const port = options.server.port; +const debug = require('debug')('jsonql-client:test:server') +const env = process.env.NODE_ENV; +// why the fuck? +jsonqlMiddleware = jsonqlKoa.default + +const dummy = () => { + return async function(ctx, next) { + // debug(ctx.path) + if (ctx.path === '/test') { + ctx.status = 200; + ctx.body = JSON.stringify({'message': 'Hello world'}) + return; + } + await next() + } +} + +module.exports = function(config = {}) { + const { stop } = serverIoCore({ + webroot: [ + __dirname, + join(__dirname, '..', '..', 'node_modules'), + join(__dirname, '..', '..', 'dist') + ], + // open: true, + // debugger: true, + port: port, + // reload: true, //env !== 'test', @BUG it keep reload not sure what is the problem at the moment + middlewares: [ + favicon(join(__dirname, 'favicon.ico')), + // dummy(), + jsonqlMiddleware(Object.assign({ + // enableAuth: true, + resolverDir: join(__dirname, 'resolvers'), + contractDir: join(__dirname, 'contracts', 'tmp') + }, config)) + ] + }); + return stop; +} diff --git a/packages/@jsonql/client/tests/fn.test.js b/packages/@jsonql/client/tests/fn.test.js new file mode 100644 index 0000000000000000000000000000000000000000..3bcebfc21c3767bec1b3d62c088fd1a4080a0aff --- /dev/null +++ b/packages/@jsonql/client/tests/fn.test.js @@ -0,0 +1,14 @@ +const test = require('ava') + +const { isKeyInObject } = require('jsonql-params-validator') + + +test('It should have isKeyInObject exported', t => { + const obj = {query: false, mutation: null, auth: true} + + t.true(isKeyInObject(obj, 'query')) + t.true(isKeyInObject(obj, 'mutation')) + + t.false(isKeyInObject(obj, 'socket')) + +}) diff --git a/packages/@jsonql/client/tests/qunit/run-qunit-setup.js b/packages/@jsonql/client/tests/qunit/run-qunit-setup.js new file mode 100644 index 0000000000000000000000000000000000000000..45bd02a1b8651276a824a17ff094176d90c43e68 --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/run-qunit-setup.js @@ -0,0 +1,56 @@ +// this will grab the list of test files +// inject into the html and run the server +const glob = require('glob') +const { join, resolve } = require('path') +const serverIoCore = require('server-io-core') +const jsonqlKoaMiddleware = require('@jsonql/koa') +const jsonqlKoaDir = join(__dirname, '..', 'fixtures') +const jsonqlKoa = jsonqlKoaMiddleware.default +/** + * @param {object} config configuration + * @return {object} promise resolve the config for server-io-core + */ +const getConfig = (config) => { + const baseDir = join(config.baseDir, 'qunit', 'tests') + // console.info('baseDir', baseDir, config.testFilePattern) + return new Promise((resolver, rejecter) => { + glob(join(baseDir, config.testFilePattern), function(err, files) { + // console.info('files found', files) + if (err || !files.length) { + console.error('FAILED TO FETCH ANY TEST FILES!') + return rejecter(err) + } + // now start the server + let opts = { + port: config.port, + webroot: config.webroot, + open: config.open, + reload: config.reload, + inject: { + insertBefore: false, + target: { + body: files.map( file => file.replace(baseDir, '') ) + } + }, + middlewares: [ + jsonqlKoa({ + // enableAuth: true, + // useJwt: true, + // keysDir: join(jsonqlKoaDir, 'keys'), + resolverDir: join(jsonqlKoaDir, 'resolvers'), + contractDir: join(jsonqlKoaDir, 'contracts', 'tmp') + }) + ] + } + resolver(opts) + }) + }) +} +// export it +module.exports = async function runQunit(userConfig) { + return getConfig(userConfig) + .then(serverIoCore) + .catch(err => { + console.error(err) + }) +} diff --git a/packages/@jsonql/client/tests/qunit/run-qunit.js b/packages/@jsonql/client/tests/qunit/run-qunit.js new file mode 100644 index 0000000000000000000000000000000000000000..f2bfbac76781ba706f340f759b7a37ef75797809 --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/run-qunit.js @@ -0,0 +1,17 @@ + +const runQunitSetup = require('./run-qunit-setup') +const config = { + "port": 8081, + "webroot": [ + "./tests/qunit/webroot", + "./tests/qunit/tests", + "./dist", + "./node_modules" + ], + "open": true, + "reload": true, + "testFilePattern": "*-test.js", + "baseDir": "tests" +} + +runQunitSetup(config) diff --git a/packages/@jsonql/client/tests/qunit/tests/base-test.js b/packages/@jsonql/client/tests/qunit/tests/base-test.js new file mode 100644 index 0000000000000000000000000000000000000000..1cff15984cb09357033c233a1c8d0c8d1c43736f --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/tests/base-test.js @@ -0,0 +1,28 @@ +// The basic test copy from main.test.js + +QUnit.test('jsonqlClient should able to connect to server', function(assert) { + var done1 = assert.async() + var done2 = assert.async() + + jsonqlClient({ + hostname: 'http://localhost:8081', + showContractDesc: true, + keepContract: false, + debugOn: false + }) + .then(function(client) { + + client.query.helloWorld().then(function(result) { + assert.equal('Hello world!', result, "Hello world test done") + + done1() + }) + + client.query.getSomething(1).catch(err => { + assert.equal(err.className, 'JsonqlValidationError', 'Expect validation error') + done2() + }) + + }) + +}) diff --git a/packages/@jsonql/client/tests/qunit/tests/static-test.js b/packages/@jsonql/client/tests/qunit/tests/static-test.js new file mode 100644 index 0000000000000000000000000000000000000000..0c1cbf16501fcc509d418cf7c33efa48730d597a --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/tests/static-test.js @@ -0,0 +1,42 @@ + + +QUnit.test('jsonqlClientStatic should able to connect to server', function(assert) { + var done1 = assert.async() + var done2 = assert.async() + // init client + var client = jsonqlClientStatic({ + hostname: 'http://localhost:8081', + showContractDesc: true, + keepContract: false, + debugOn: true + }) + + client.query('getSomethingNonExisted', 'whatever') + .then(function(result) { + console.log('[Qunit]', 'getSomething result', result) + }) + + client.query('getSomething', 'whatever', 'shit') + .then(function(result) { + console.log('[Qunit]', 'getSomething result', result) + assert.equal(true, typeof result.whatever === 'string', 'just passing this one') + done2() + }) + .catch(function(error) { + console.error('[Qunit]', 'some error happend?', error) + done2() + }) + + client.query('helloWorld') + .then(function(result) { + console.info(result) + assert.equal('Hello world!', result, "Hello world test done") + done1() + }) + .catch(function(error) { + console.error('[Qunit]', 'catch', error) + done1() + }) + + +}) diff --git a/packages/@jsonql/client/tests/qunit/webroot/index.html b/packages/@jsonql/client/tests/qunit/webroot/index.html new file mode 100644 index 0000000000000000000000000000000000000000..78922bbbcc4197c0887bc79c433c91046a7ec4d6 --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/webroot/index.html @@ -0,0 +1,34 @@ + + + + + + QUnit testing for jsonql-client + + + +
+
+ + + + + + + + + + + + + + + + + diff --git a/packages/@jsonql/client/tests/qunit/webroot/nb-qunit-helper.js b/packages/@jsonql/client/tests/qunit/webroot/nb-qunit-helper.js new file mode 100644 index 0000000000000000000000000000000000000000..244d29fa4ef29243af9a568ba2bc2b9e83b77a0b --- /dev/null +++ b/packages/@jsonql/client/tests/qunit/webroot/nb-qunit-helper.js @@ -0,0 +1,31 @@ +// This is a helper file that hook up to the server-io-core debugger system +// to push the result back to the console to display it +// if you don't need this then just remove it from index.html file +;(function(){ + var errors = [] + var i = 0; + QUnit.log(function(res){ + ++i; + if (!res || !res.result){ + errors.push(res) + } + if (i%50 == 0) { // why 50? + var data = { + tests_run: i, + tracebacks: errors, + url : window.location.pathname + } + errors = []; + // send back to the console + console.debug(data) + } + }) + + QUnit.done(function(results){ + results.tracebacks = errors; + results.url = window.location.pathname; + // send back to the console + console.debug(results) + }) + +})(); diff --git a/packages/@jsonql/koa/README.md b/packages/@jsonql/koa/README.md index 31697a27099853f7083d159da691df3f0fd72533..43d59f6460cc94e24bd77ccab2102b8d76b08adc 100644 --- a/packages/@jsonql/koa/README.md +++ b/packages/@jsonql/koa/README.md @@ -1,61 +1,9 @@ # @jsonql/koa -> The complete jsonql api server with Koa +> This is the jsonql middleware previously published as jsonql-koa, and completely rewritten with ES6 -It comes with `koa-cors`, `koa-bodyparser`. - -## Installation - -```sh -$ npm i @jsonql/koa -``` - -## How to - -Just import and pass a `config` (or nothing to use all the default options) - -```js -const jsonqlKoa = require('@jsonql/koa') -const { join } = require('path') - -const { app, server, stop } = jsonqlKoa({ - resolverDir: join(__dirname, 'resolvers'), // default - contractDir: join(__dirname, 'contract') // default -}) -``` - -By default it will start on the port `8001` if you want to change it, -pass `port` to the `config`. - -```js -const jsonqlKoa = require('@jsonql/koa') -const { app, server, stop } = jsonqlKoa({ - port: 7890 -}) -``` - -As you can see from the example, it return the following object - -- app - the Koa app instance -- server - the underlying `http.server` -- stop - a function to call and close the server - -## TODO - -We will add the file upload interface, socket server and other new features in the later release. +Please check [jsonql.org](https://jsonql.js.org) for more information. --- -Joel Chu (c) 2019 - - -"dependencies": { - "debug": "^4.1.1", - "jsonql-koa": "^1.3.8", - "koa": "^2.8.1", - "koa-bodyparser": "^4.2.1", - "koa-cors": "0.0.16" -}, -"devDependencies": { - "superkoa": "^1.0.3" -} +NB & T1S diff --git a/packages/@jsonql/koa/index.js b/packages/@jsonql/koa/index.js index 5ff0e9ca5cae94e3bbcb9afac78379fbd27447a7..f7df12b228ee0b46e8f4707c189ba695f3cd9cd9 100644 --- a/packages/@jsonql/koa/index.js +++ b/packages/@jsonql/koa/index.js @@ -1,40 +1,47 @@ -// the main file -const debug = require('debug')('@jsonql_koa:main') -const Koa = require('koa') -const cors = require('koa-cors') -const bodyparser = require('koa-bodyparser') -const jsonql = require('jsonql-koa') -const DEFAULT_PORT = 8001; - - /** - * @param {object} [config={}] configuration - * @return {object} app, server, stop + * This is the main interface to export the middleware(s) + * we will take the config here and export array of middleware using koa-compose */ -module.exports = function(config = {}) { - - const port = getConfigValue('port', config) || DEFAULT_PORT; - //('port' in config) ? config.port : 8001; - - const app = new Koa() - let noCors = getConfigValue('cors', config) - if (noCors === undefined || noCors !== false) { - debug(`use cors plugin`) - app.use(cors()) - } - app.use(bodyparser()) - app.use(jsonql(config)) - - const server = app.listen(port) - const stop = () => { - debug(`stop @jsonql/koa server`) - server.close() +import fs from 'fs' +import { merge } from 'lodash' +import compose from 'koa-compose' +import { + coreMiddleware, + authMiddleware, + contractMiddleware, + helloMiddleware, + consoleMiddleware, + publicMethodMiddleware, + initMiddleware +} from './src/middlewares' +import { configCheck } from './src/options' +import { getDebug } from './src/utils' +const debug = getDebug('main') +// main +export default function jsonqlKoa(config = {}) { + // first check the config + const opts = configCheck(config) + debug('[jsonql-koa] init opts', opts) + // export + let middlewares = [ + initMiddleware(opts), + helloMiddleware(opts), + contractMiddleware(opts) + ] + // only available when enable it + if (config.enableWebConsole) { + middlewares.push(consoleMiddleware(opts)) } - debug(`@jsonql/koa server started on @${port}`) - return { - app, - server, - stop + if (opts.enableAuth) { + middlewares.push( + publicMethodMiddleware(opts), + authMiddleware(opts) + ) } + middlewares.push( + coreMiddleware(opts) + ) + // finally + return compose(middlewares) } diff --git a/packages/@jsonql/koa/main.js b/packages/@jsonql/koa/main.js new file mode 100644 index 0000000000000000000000000000000000000000..188245a229d0ee6d6c685eaed77232af23df0cc9 --- /dev/null +++ b/packages/@jsonql/koa/main.js @@ -0,0 +1,3 @@ +// export for CJS modules using esm modules +require = require('esm')(module) +module.exports = require('./index.js') diff --git a/packages/@jsonql/koa/package.json b/packages/@jsonql/koa/package.json index 2cad776cfd73344c130a22d42f906c5140c7f0b2..79e803c32bfa5ae30317e839ebe8533561196dad 100644 --- a/packages/@jsonql/koa/package.json +++ b/packages/@jsonql/koa/package.json @@ -1,19 +1,26 @@ { "name": "@jsonql/koa", - "version": "0.1.0", - "description": "Complete jsonql Koa setup + extra in later release", - "main": "index.js", + "version": "0.2.5", + "description": "jsonql Koa middleware", + "main": "main.js", + "module": "index.js", + "files": [ + "src", + "index.js", + "main.js" + ], "scripts": { "test": "ava --verbose", + "prepare": "npm run test", "start": "node ./test/fixtures/start.js", "test:debug": "DEBUG=jsonql* ava --verbose", "coverage": "nyc ava --verbose", + "test:basic": "DEBUG=jsonql* ava ./tests/koa.test.js", "test:notfound": "DEBUG=jsonql-koa* ava --verbose ./tests/resolverNotFound.test.js", "test:es6": "DEBUG=jsonql-koa* ava --verbose ./tests/es6-module.test.js", "test:jwt": "DEBUG=jsonql-koa*,jsonql-jwt* ava ./tests/jwt.test.js", "test:jwt-auth": "DEBUG=jsonql-koa* ava ./tests/jwt-auth.test.js", "test:fail": "ava ./tests/fail.test.js", - "test:basic": "DEBUG=jsonql* ava ./tests/koa.test.js", "test:contract": "DEBUG=jsonql-koa* ava ./tests/contractWithAuth.test.js", "test:auth": "DEBUG=jsonql* ava ./tests/auth.test.js", "test:error": "DEBUG=jsonql-koa* ava ./tests/resolverNotFound.test.js", @@ -36,10 +43,6 @@ ], "author": "Joel Chu ", "license": "ISC", - "devDependencies": { - "ava": "^2.3.0", - "superkoa": "^1.0.3" - }, "repository": { "type": "git", "url": "git+ssh://git@gitee.com:to1source/jsonql.git" @@ -54,6 +57,9 @@ "!tests/helpers/*.*", "!tests/fixtures/*.*" ], + "require": [ + "esm" + ], "cache": true, "concurrency": 5, "failFast": true, @@ -62,9 +68,28 @@ "compileEnhancements": false }, "dependencies": { - "jsonql-koa": "^1.3.8", + "esm": "^3.2.25", + "fs-extra": "^8.1.0", + "jsonql-constants": "^1.8.3", + "jsonql-contract": "^1.7.8", + "jsonql-errors": "^1.1.3", + "jsonql-jwt": "^1.3.2", + "jsonql-node-client": "^1.1.8", + "jsonql-params-validator": "^1.4.11", + "jsonql-resolver": "^0.8.7", + "jsonql-utils": "^0.6.10", + "jsonql-web-console": "^0.4.3", "koa": "^2.8.1", + "koa-compose": "^4.1.0", + "lodash": "^4.17.15" + }, + "devDependencies": { + "ava": "^2.4.0", + "jwt-decode": "^2.2.0", "koa-bodyparser": "^4.2.1", - "koa-cors": "0.0.16" + "nyc": "^14.1.1", + "request": "^2.88.0", + "server-io-core": "^1.2.0", + "superkoa": "^1.0.3" } } diff --git a/packages/@jsonql/koa/src/contracts/contract-generator.js b/packages/@jsonql/koa/src/contracts/contract-generator.js index 364b4c60f5c69a485afb4db7839dea0b9c642f4b..eb2325e78a6a4330ffde3e46b82c246444e900cc 100644 --- a/packages/@jsonql/koa/src/contracts/contract-generator.js +++ b/packages/@jsonql/koa/src/contracts/contract-generator.js @@ -1,14 +1,14 @@ // this need to get call from the beginning // so make this available in different places -const fsx = require('fs-extra') -const { join } = require('path') -const contractApi = require('jsonql-contract') -const { +import fsx from 'fs-extra' +import { join } from 'path' +import contractApi from 'jsonql-contract' +import { DEFAULT_CONTRACT_FILE_NAME, PUBLIC_CONTRACT_FILE_NAME -} = require('jsonql-constants') - -const debug = require('debug')('jsonql-koa::contract-generator') +} from 'jsonql-constants' +import { getDebug } from '../utils' +const debug = getDebug('contract-generator') /** * @param {string} contractDir where the contract is * @param {boolean} pub system of public @@ -45,7 +45,7 @@ const contractGenerator = function(opts, pub = false, start = false) { } // export -module.exports = { +export { contractGenerator, readContract } diff --git a/packages/@jsonql/koa/src/contracts/get-contract.js b/packages/@jsonql/koa/src/contracts/get-contract.js new file mode 100644 index 0000000000000000000000000000000000000000..cda821a2cf8b77bcc76bb787fe5ea89d8c719251 --- /dev/null +++ b/packages/@jsonql/koa/src/contracts/get-contract.js @@ -0,0 +1,42 @@ +// move all the code into it's folder +// we are going to fork the process to lighten the load when it start +import { fork } from 'child_process' +import { join } from 'path' + +import { getDebug } from '../utils' +const debug = getDebug('contract-generator') +// try to cache it +let contractCache = {}; +/** + * getContract main + * @param {object} config options + * @param {boolean} pub public contract or not + * @return {object} Promise to resolve the contract json + */ +export function getContract(config, pub = false) { + const ps = fork(join(__dirname, 'run.js')) + const key = pub ? 'public' : 'private'; + if (contractCache[key]) { + debug(`return ${key} contract from cache`, contractCache[key]) + // this is the problem - if we want to keep it consistent then + // we should always provide the contract key --> cache is optional! + // { contract: contractCache[key], cache: true } + return Promise.resolve(contractCache[key]) + } + ps.send({ config, pub }) + // return + return new Promise((resolver, rejecter) => { + ps.on('message', msg => { + if (msg.contract) { + // contractCache[key] = msg.contract; // <-- disable cache + // return + return resolver(msg.contract) + } + rejecter(msg) + }) + ps.on('error', err => { + debug('ps error', err) + rejecter(err) + }) + }) +} diff --git a/packages/@jsonql/koa/src/contracts/helpers.js b/packages/@jsonql/koa/src/contracts/helpers.js new file mode 100644 index 0000000000000000000000000000000000000000..48d9badd2d8fac085a88840975fbf1ce45d2815a --- /dev/null +++ b/packages/@jsonql/koa/src/contracts/helpers.js @@ -0,0 +1,94 @@ +// all these methods were inside the contract-middleware +// now move all of them here to keep the middleware clean +import { trim } from 'lodash' +import { SHOW_CONTRACT_DESC_PARAM } from 'jsonql-constants' +import { + isKeyInObject, + getDebug, + handleOutput, + packResult, + ctxErrorHandler +} from '../utils' +const debug = getDebug('contracts:helpers') +/** + * remove the description field + * @param {boolean} showDesc true to keep + * @param {object} contract json + * @return {object} clean contract + */ +export const removeDesc = (showDesc, contract) => { + debug('showDesc', showDesc) + if (showDesc) { + return contract; + } + let c = contract; + for (let type in c) { + for (let fn in c[type]) { + if (isKeyInObject(c[type][fn], 'description')) { + delete c[type][fn].description; + if (c[type][fn].returns && isKeyInObject(c[type][fn].returns, 'description')) { + delete c[type][fn].returns.description; + } + } + } + } + return c; +} + +/** + * get the contract data @TODO might require some sort of security here + * @param {object} opts options + * @param {object} ctx koa + * @return {undefined} + */ +export const handleContract = (opts, ctx, contract) => { + // @1.3.2 add a filter here to exclude the description field + // just to reduce the size, but we serve it up if this is request with + // desc=1 param - useful for the jsonql-web-console + // debug('handleContract', ctx.query.desc) + const key = Object.keys(SHOW_CONTRACT_DESC_PARAM)[0] + let desc = !!(ctx.query[key] && ctx.query[key] === SHOW_CONTRACT_DESC_PARAM[key]) + handleOutput(opts)(ctx, packResult( + removeDesc(desc, contract) + )) +} + +/** + * Search for the value from the CONTRACT_KEY_NAME + * @param {object} ctx koa context + * @param {string} contractKeyName the key to search + * @return {string} the value from header + */ +export const searchContractAuth = function(ctx, contractKeyName) { + // debug(`Try to get ${contractKeyName} from header`, ctx.request.header); + return ctx.request.get(contractKeyName) +} + +/** + * Handle contract authorisation using a key + * @param {object} ctx koa + * @param {object} opts options + * @return {boolean} true ok + */ +export const contractAuth = function(ctx, opts) { + if (opts.contractKey !== false && opts.contractKeyName !== false) { + const { contractKey, contractKeyName } = opts; + // debug('Received this for auth', contractKeyName, contractKey); + // @2019-05-08 we change from url query to header + // const keyValueFromClient = trim(ctx.query[contractKeyName]); + // debug('the query value', ctx.query); + const keyValueFromClient = searchContractAuth(ctx, contractKeyName) + + switch (true) { + case typeof contractKey === 'string': + // debug('compare this two', keyValueFromClient, contractKey); + return keyValueFromClient === contractKey; + break; + default: + // @TODO what if we want to read the header? + debug('Unsupported contract auth type method', typeof contractKey) + return false; + } + } + return true; +} diff --git a/packages/@jsonql/koa/src/contracts/import.js b/packages/@jsonql/koa/src/contracts/import.js new file mode 100644 index 0000000000000000000000000000000000000000..85b8689af02ce754a41e8c89b9f1299fb50b80e8 --- /dev/null +++ b/packages/@jsonql/koa/src/contracts/import.js @@ -0,0 +1,2 @@ +require = require('esm')(module) +module.exports = require('./contract-generator.js') diff --git a/packages/@jsonql/koa/src/contracts/index.js b/packages/@jsonql/koa/src/contracts/index.js index 2e334287e8df84e3233d9d993fe40b43901fa2e3..c824080a7a62fde65352854f69c7ce2ea4c5b5ca 100644 --- a/packages/@jsonql/koa/src/contracts/index.js +++ b/packages/@jsonql/koa/src/contracts/index.js @@ -1,40 +1,9 @@ -// move all the code into it's folder -// we are going to fork the process to lighten the load when it start -const { fork } = require('child_process') -const { join } = require('path') -const debug = require('debug')('jsonql-koa:contract-generator') -// try to cache it -let contractCache = {}; -/** - * getContract main - * @param {object} config options - * @param {boolean} pub public contract or not - * @return {object} Promise to resolve the contract json - */ -module.exports = function(config, pub = false) { - const ps = fork(join(__dirname, 'run.js')) - const key = pub ? 'public' : 'private'; - if (contractCache[key]) { - debug(`return ${key} contract from cache`, contractCache[key]) - // this is the problem - if we want to keep it consistent then - // we should always provide the contract key --> cache is optional! - // { contract: contractCache[key], cache: true } - return Promise.resolve(contractCache[key]) - } - ps.send({ config, pub }) - // return - return new Promise((resolver, rejecter) => { - ps.on('message', msg => { - if (msg.contract) { - // contractCache[key] = msg.contract; // <-- disable cache - // return - return resolver(msg.contract) - } - rejecter(msg) - }) - ps.on('error', err => { - debug('ps error', err) - rejecter(err) - }) - }) +// import export +import { getContract } from './get-contract' +import { handleContract, contractAuth } from './helpers' + +export { + getContract, + handleContract, + contractAuth } diff --git a/packages/@jsonql/koa/src/contracts/process-contract.js b/packages/@jsonql/koa/src/contracts/process-contract.js index 9a6a4a4eba0279510c8b5426e8c65a3cd6bed59c..80fd40b85c75db6c91182f0c7cd9524e9c1fcac4 100644 --- a/packages/@jsonql/koa/src/contracts/process-contract.js +++ b/packages/@jsonql/koa/src/contracts/process-contract.js @@ -1,6 +1,6 @@ // wrap the method in the init-middleware here -const { JsonqlError } = require('jsonql-errors') -const { isContractJson, getDebug } = require('../utils') +import { JsonqlError } from 'jsonql-errors' +import { isContract, getDebug } from '../utils' const debug = getDebug('process-contract') /** @@ -10,7 +10,7 @@ const debug = getDebug('process-contract') */ const getFromOpts = opts => { return Promise.resolve( - isContractJson(opts.contract) + isContract(opts.contract) ) } @@ -19,7 +19,7 @@ const getFromOpts = opts => { * @param {object} opts configuration * @return {object} promise to resolve the contract */ -module.exports = async function processContract(ctx, opts) { +export default async function processContract(ctx, opts) { // const { setter, getter } = ctx.state.jsonql; return getFromOpts(opts) .then(c => c || false) diff --git a/packages/@jsonql/koa/src/contracts/run.js b/packages/@jsonql/koa/src/contracts/run.js index 6dcbb6947bf79fc07999b52f20d15cf48cee82e2..378f8ab3da6043fc3a3bd72fb3a9d4f20dee70d3 100644 --- a/packages/@jsonql/koa/src/contracts/run.js +++ b/packages/@jsonql/koa/src/contracts/run.js @@ -1,5 +1,6 @@ // /lib/contract-generator/run.js -const { contractGenerator, readContract } = require('./contract-generator') +// @BUG throw error when we call this using ES6 +const { contractGenerator, readContract } = require('./import') // listening process.on('message', m => { const { config, pub } = m; diff --git a/packages/@jsonql/koa/src/index.js b/packages/@jsonql/koa/src/index.js deleted file mode 100644 index 3098a81d5e469273a75ea9c98188d37a17ad0860..0000000000000000000000000000000000000000 --- a/packages/@jsonql/koa/src/index.js +++ /dev/null @@ -1 +0,0 @@ -// completely reorganize the folder structure etc diff --git a/packages/@jsonql/koa/src/middlewares/auth-middleware.js b/packages/@jsonql/koa/src/middlewares/auth-middleware.js index 377f82eff3e4ecfefe8231cde8edda8df8d3911b..fea1cc12edf8c564c6f6d001a7c32b16066ecd6d 100644 --- a/packages/@jsonql/koa/src/middlewares/auth-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/auth-middleware.js @@ -1,32 +1,34 @@ // jsonql-auth middleware -const { +import { AUTH_TYPE, ISSUER_NAME, VALIDATOR_NAME, AUTH_CHECK_HEADER, BEARER -} = require('jsonql-constants') -const { +} from 'jsonql-constants' +import { chainFns, getDebug, packResult, headerParser, printError, - isObject, isNotEmpty, handleOutput, forbiddenHandler, ctxErrorHandler, - createTokenValidator -} = require('./lib') -const { + + createTokenValidator, // import from the jwt + + isObject +} from '../utils' +import { JsonqlResolverNotFoundError, JsonqlAuthorisationError, JsonqlValidationError, finalCatch -} = require('jsonql-errors') -const { getLocalValidator } = require('jsonql-resolver') -const { trim } = require('lodash') +} from 'jsonql-errors' +import { getLocalValidator } from 'jsonql-resolver' +import { trim } from 'lodash' const debug = getDebug('auth-middleware') @@ -111,7 +113,7 @@ const getValidator = (config, type, contract) => { * handle the actual authentication * @TODO need to break this down further at the moment its very hard to debug what is going on here */ -module.exports = function(config) { +export default function authMiddleware(config) { // return middleware return async function(ctx, next) { // we should only care if there is api call involved diff --git a/packages/@jsonql/koa/src/middlewares/console-middleware.js b/packages/@jsonql/koa/src/middlewares/console-middleware.js index 637c4d3d1c531ac61a467422584e2beb23085749..af05a67229944f1a85b4799a25f6061070354e50 100644 --- a/packages/@jsonql/koa/src/middlewares/console-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/console-middleware.js @@ -1,8 +1,8 @@ // This will be handling the json:ql console -const { isJsonqlConsoleUrl } = require('./lib') -const webConsole = require('jsonql-web-console') +import webConsole from 'jsonql-web-console' +import { isJsonqlConsoleUrl } from '../utils' // export -module.exports = function(opts) { +export default function consoleMiddleware(opts) { return webConsole(opts, isJsonqlConsoleUrl) } diff --git a/packages/@jsonql/koa/src/middlewares/contract-middleware.js b/packages/@jsonql/koa/src/middlewares/contract-middleware.js index 6bdade1088d40e73e7289f791121c2e3dcbc451e..a789597d6be50a1904ae987e00f87157dd61504d 100644 --- a/packages/@jsonql/koa/src/middlewares/contract-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/contract-middleware.js @@ -2,114 +2,26 @@ // the reason is, it will get re-use by subsequences middlewares // so we might as well do this here // Also we could hijack it off and serve the html files up for documentation purpose - -const fsx = require('fs-extra') -const { join } = require('path') -const { trim } = require('lodash') -const { CONTRACT_NAME, SHOW_CONTRACT_DESC_PARAM } = require('jsonql-constants') -const { JsonqlContractAuthError } = require('jsonql-errors') -const { isKeyInObject } = require('jsonql-params-validator') -const { - getDebug, +import { CONTRACT_NAME } from 'jsonql-constants' +import { getContract, - handleOutput, - packResult, - isContractJson, + handleContract, + contractAuth +} from '../contracts' +import { + getDebug, ctxErrorHandler -} = require('./lib') +} from '../utils' const debug = getDebug('contract-middleware') -/** - * remove the description field - * @param {boolean} showDesc true to keep - * @param {object} contract json - * @return {object} clean contract - */ -const removeDesc = (showDesc, contract) => { - debug('showDesc', showDesc) - if (showDesc) { - return contract; - } - let c = contract; - for (let type in c) { - for (let fn in c[type]) { - if (isKeyInObject(c[type][fn], 'description')) { - delete c[type][fn].description; - if (c[type][fn].returns && isKeyInObject(c[type][fn].returns, 'description')) { - delete c[type][fn].returns.description; - } - } - } - } - return c; -} - -/** - * get the contract data @TODO might require some sort of security here - * @param {object} opts options - * @param {object} ctx koa - * @return {undefined} - */ -const handleContract = (opts, ctx, contract) => { - // @1.3.2 add a filter here to exclude the description field - // just to reduce the size, but we serve it up if this is request with - // desc=1 param - useful for the jsonql-web-console - // debug('handleContract', ctx.query.desc) - const key = Object.keys(SHOW_CONTRACT_DESC_PARAM)[0] - let desc = !!(ctx.query[key] && ctx.query[key] === SHOW_CONTRACT_DESC_PARAM[key]) - handleOutput(opts)(ctx, packResult( - removeDesc(desc, contract) - )) -} - -/** - * Search for the value from the CONTRACT_KEY_NAME - * @param {object} ctx koa context - * @param {string} contractKeyName the key to search - * @return {string} the value from header - */ -const searchContractAuth = function(ctx, contractKeyName) { - // debug(`Try to get ${contractKeyName} from header`, ctx.request.header); - return ctx.request.get(contractKeyName) -} - -/** - * Handle contract authorisation using a key - * @param {object} ctx koa - * @param {object} opts options - * @return {boolean} true ok - */ -const contractAuth = function(ctx, opts) { - if (opts.contractKey !== false && opts.contractKeyName !== false) { - const { contractKey, contractKeyName } = opts; - // debug('Received this for auth', contractKeyName, contractKey); - // @2019-05-08 we change from url query to header - // const keyValueFromClient = trim(ctx.query[contractKeyName]); - // debug('the query value', ctx.query); - const keyValueFromClient = searchContractAuth(ctx, contractKeyName) - - switch (true) { - case typeof contractKey === 'string': - // debug('compare this two', keyValueFromClient, contractKey); - return keyValueFromClient === contractKey; - break; - default: - // @TODO what if we want to read the header? - debug('Unsupported contract auth type method', typeof contractKey) - return false; - } - } - return true; -} - /** * @TODO is there a bug in here somewhere that I am not aware of * it seems to me that everytime the middleware get call, it keep trying to * generate contract, or reading from the contract, which is not ideal * it should able to cache it some how? */ -module.exports = function(opts) { +export default function contractMiddleware(opts) { // export return async function(ctx, next) { // this will only handle certain methods diff --git a/packages/@jsonql/koa/src/middlewares/core-middleware.js b/packages/@jsonql/koa/src/middlewares/core-middleware.js index 234e748867287030013b54a6b429cbf8fe322e89..fdf8c607d8082077973ac846e83f7ab0461984ac 100644 --- a/packages/@jsonql/koa/src/middlewares/core-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/core-middleware.js @@ -1,6 +1,7 @@ // The core of the jsonql middleware -const { QUERY_NAME, MUTATION_NAME } = require('jsonql-constants') -const { getDebug, resolveMethod } = require('./lib') +import { QUERY_NAME, MUTATION_NAME } from 'jsonql-constants' +import { resolveMethod } from 'jsonql-resolver' +import { getDebug } from '../utils' const debug = getDebug('core') /** @@ -8,7 +9,7 @@ const debug = getDebug('core') * @param {object} config options * @return {mixed} depends whether if we catch the call */ -module.exports = function(opts) { +export default function coreMiddleware(opts) { // ouput the middleware return async function(ctx, next) { if (ctx.state.jsonql.isReq) { diff --git a/packages/@jsonql/koa/src/middlewares/hello-middleware.js b/packages/@jsonql/koa/src/middlewares/hello-middleware.js index 4b151e78e26220294dde7eba2fcf1c0255dcdc71..1f72b576e405680ce39df03280f186ba65ffc19f 100644 --- a/packages/@jsonql/koa/src/middlewares/hello-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/hello-middleware.js @@ -1,9 +1,9 @@ // The helloWorld should always be available. Because this can serve as a ping even when its auth:true -const { getDebug, handleOutput, packResult } = require('./lib') -const { HELLO, HELLO_FN, QUERY_NAME } = require('jsonql-constants') +import { getDebug, handleOutput, packResult } from '../utils' +import { HELLO, HELLO_FN, QUERY_NAME } from 'jsonql-constants' const debug = getDebug('hello-middlware') // export -module.exports = function(opts) { +export default function helloMiddleware(opts) { return async function(ctx, next) { const { isReq, resolverType, resolverName } = ctx.state.jsonql; // so here we check two things, the header and the url if they match or not diff --git a/packages/@jsonql/koa/src/middlewares/index.js b/packages/@jsonql/koa/src/middlewares/index.js index fc69da0f45caa0401aeec7f0e764060fc934f895..1b90a4958205cfc3da2ffa5c1f8f35820ea43af8 100644 --- a/packages/@jsonql/koa/src/middlewares/index.js +++ b/packages/@jsonql/koa/src/middlewares/index.js @@ -1,18 +1,18 @@ // main export interface -const authMiddleware = require('./auth-middleware') -const coreMiddleware = require('./core-middleware') -const contractMiddleware = require('./contract-middleware') -const helloMiddleware = require('./hello-middleware') +import authMiddleware from './auth-middleware' +import coreMiddleware from './core-middleware' +import contractMiddleware from './contract-middleware' +import helloMiddleware from './hello-middleware' -const consoleMiddleware = require('./console-middleware') -const publicMethodMiddleware = require('./public-method-middleware') -const errorsHandlerMiddleware = require('./errors-handler-middleware') -const initMiddleware = require('./init-middleware') +import consoleMiddleware from './console-middleware' +import publicMethodMiddleware from './public-method-middleware' +// import errorsHandlerMiddleware from './errors-handler-middleware' +import initMiddleware from './init-middleware' // export -module.exports = { - configCheck, +export { + // configCheck, consoleMiddleware, authMiddleware, @@ -21,6 +21,6 @@ module.exports = { helloMiddleware, publicMethodMiddleware, - errorsHandlerMiddleware, + // errorsHandlerMiddleware, initMiddleware } diff --git a/packages/@jsonql/koa/src/middlewares/init-middleware.js b/packages/@jsonql/koa/src/middlewares/init-middleware.js index afa9e887b50f098b953b92bacae135d006f186b9..214c900cf7fe59785575331879efd13a6a391948 100644 --- a/packages/@jsonql/koa/src/middlewares/init-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/init-middleware.js @@ -1,15 +1,16 @@ // this will be the first part of the middleware that checkout the // headers and request and extract the parts that we need for the operation -const { +import { inArray, getDebug, isJsonqlRequest, - isContractJson, isObject, ctxErrorHandler, - processJwtKeys -} = require('./lib') -const { + processJwtKeys, + getQueryFromPayload, + getMutationFromPayload +} from '../utils' +import { AUTH_TYPE, QUERY_NAME, MUTATION_NAME, @@ -20,10 +21,10 @@ const { CONDITION_PARAM_NAME, RESOLVER_PARAM_NAME, JSONP_CALLBACK_NAME -} = require('jsonql-constants') -const { Jsonql406Error } = require('jsonql-errors') -const processContract = require('./lib/contract-generator/process-contract') -const { getQueryFromPayload, getMutationFromPayload } = require('jsonql-params-validator') +} from 'jsonql-constants' +import { Jsonql406Error } from 'jsonql-errors' +import processContract from '../contracts/process-contract' +// should move to the utils as well const debug = getDebug('init-middleware') @@ -79,7 +80,7 @@ const isJsonpCall = function(ctx) { * @param {function} getter nodeCache get * @return {function} middleware */ -module.exports = function(opts) { +export default function initMiddleware(opts) { // export return async function(ctx, next) { ctx.state.jsonql = {}; diff --git a/packages/@jsonql/koa/src/middlewares/public-method-middleware.js b/packages/@jsonql/koa/src/middlewares/public-method-middleware.js index 162a208b6ede156753045fe5d4f0370467eee0e4..c95483124fea7f067ff9edbbceb67082813565d7 100644 --- a/packages/@jsonql/koa/src/middlewares/public-method-middleware.js +++ b/packages/@jsonql/koa/src/middlewares/public-method-middleware.js @@ -1,15 +1,14 @@ // we need to let this middleware take the public method first before // running pass to the auth-middleware otherwise, it will not able to // get to the next one -const { QUERY_NAME, MUTATION_NAME, AUTH_TYPE } = require('jsonql-constants') -const { resolveMethod, handleAuthMethods } = require('jsonql-resolver') - -const { getDebug, extractParamsFromContract } = require('./lib') +import { QUERY_NAME, MUTATION_NAME, AUTH_TYPE } from 'jsonql-constants' +import { resolveMethod, handleAuthMethods } from 'jsonql-resolver' +import { getDebug, extractParamsFromContract } from '../utils' const debug = getDebug('public-method-middleware') // main export -module.exports = function(opts) { +export default function publicMethodMiddleware(opts) { return async function(ctx, next) { const { isReq, resolverType, resolverName, payload, contract } = ctx.state.jsonql; // we pre-check if this is auth enable, if it's not then let the other middleware to deal with it diff --git a/packages/@jsonql/koa/src/options/index.js b/packages/@jsonql/koa/src/options/index.js index 506ddeced7c90819ab15bdaea6eed55071ad795e..d0d55fcc0820563496f16df10d04c9974daba34d 100644 --- a/packages/@jsonql/koa/src/options/index.js +++ b/packages/@jsonql/koa/src/options/index.js @@ -1,13 +1,13 @@ // wrap all the options and method in one instead of all over the places -const { join, resolve } = require('path') -const fsx = require('fs-extra') -const _ = require('lodash') -const { checkConfig, isString } = require('jsonql-params-validator') -const { rsaPemKeys } = require('jsonql-jwt') - -const { appProps, constProps, jwtProcessKey } = require('./options') -const { getContract, isContractJson, chainFns, getDebug, inArray } = require('../index') +import { join, resolve } from 'path' +import fsx from 'fs-extra' +import _ from 'lodash' +import { checkConfig, isString } from 'jsonql-params-validator' +import { rsaPemKeys } from 'jsonql-jwt' +import { appProps, constProps, jwtProcessKey } from './options' +import { isContract, chainFns, getDebug, inArray } from '../utils' +import { getContract } from '../contracts' const debug = getDebug('config-check') /** @@ -21,7 +21,7 @@ const applyGetContract = function(config) { .chain() .thru(config => { const { contract } = config; - if (isContractJson(contract)) { + if (isContract(contract)) { config.contract = contract; return [true, config] } @@ -73,7 +73,7 @@ const applyAuthOptions = function(config) { * @return {object} configuration been checked * @api public */ -module.exports = function configCheck(config) { +export function configCheck(config) { const fn = chainFns(checkConfig, applyGetContract, applyAuthOptions) return fn(config, appProps, constProps) } diff --git a/packages/@jsonql/koa/src/options/options.js b/packages/@jsonql/koa/src/options/options.js index e423dd7435b5c66a1d90d91f78d7bacf3eece440..36c6afbccea6d6cd18feb79f532f77715a6bda45 100644 --- a/packages/@jsonql/koa/src/options/options.js +++ b/packages/@jsonql/koa/src/options/options.js @@ -1,6 +1,6 @@ -const { join } = require('path'); -const fs = require('fs'); -const { +import { join } from 'path' +import fs from 'fs' +import { PUBLIC_KEY, PRIVATE_KEY, JSONQL_PATH, @@ -27,12 +27,12 @@ const { DEFAULT_PUBLIC_KEY_FILE, DEFAULT_PRIVATE_KEY_FILE, RSA_MIN_MODULE_LEN -} = require('jsonql-constants') -const { +} from 'jsonql-constants' +import { createConfig, constructConfig -} = require('jsonql-params-validator') -// const NodeCache = require('node-cache'); +} from 'jsonql-params-validator' +// const NodeCache from 'node-cache'); // const mcache = new NodeCache; // @BUG when we deploy it in docker, or using systemd the workingDirectory affect the // execute path, it might be better to allow a config option of workingDirectory and @@ -105,9 +105,9 @@ const appProps = { // For v1.5.0 to integrate the node-client clientConfig: createConfig([], [ARRAY_TYPE]) }; - -module.exports = { +const jwtProcessKey = 'INIT_JWT_KEYS' // just for id the promise call +export { constProps, appProps, - jwtProcessKey: 'INIT_JWT_KEYS' // just for id the promise call -}; + jwtProcessKey +} diff --git a/packages/@jsonql/koa/src/options/process-jwt-keys.js b/packages/@jsonql/koa/src/options/process-jwt-keys.js index d960c56d29052eefcc39946234a7e3b7ad699a86..ead53011bfc1bc9dc4c2a5320d491020179262a2 100644 --- a/packages/@jsonql/koa/src/options/process-jwt-keys.js +++ b/packages/@jsonql/koa/src/options/process-jwt-keys.js @@ -4,11 +4,11 @@ // so we need to do this in two steps // if we find a keys file, great, read it and store it // if not then wait until inside the init-middleware and call the rsaPemKeys there -const _ = require('lodash') -const fsx = require('fs-extra') -const { jwtProcessKey } = require('./options') -const { isKeyInObject, isString } = require('jsonql-params-validator') -const debug = require('debug')('jsonql-koa:process-jwt-keys') +import _ from 'lodash' +import fsx from 'fs-extra' +import { jwtProcessKey } from './options' +import { isKeyInObject } from '../utils' +import { isString } from 'jsonql-params-validator' /** * Get the keys from cache call @@ -58,7 +58,7 @@ const getCreatedKeys = (ctx, config) => { * @param {object} config configuration * @return {object} config with the privateKey and publicKey stored */ -module.exports = function processJwtKeys(ctx, config) { +export default function processJwtKeys(ctx, config) { let result; if ((result = getKeysFromCache(ctx, config)) !== false) { return result; diff --git a/packages/@jsonql/koa/src/utils/cache.js b/packages/@jsonql/koa/src/utils/cache.js index f1b19b00cd242ec431719e1b1d3e9a803f233c35..b6f2296eca717f021fcff93d2dbf2b728bdb9d4e 100644 --- a/packages/@jsonql/koa/src/utils/cache.js +++ b/packages/@jsonql/koa/src/utils/cache.js @@ -1,7 +1,12 @@ // hope this will solve the missing contract of what not problem once and for all -const nodeCache = require('node-cache') +import nodeCache from 'node-cache' +import { getDebug } from './utils' + const cache = new nodeCache() -const debug = require('debug')('jsonql-koa:node-cache') +const debug = getDebug('node-cache') + +// @TODO perhaps we should have an extra key if it's presented + /** * @param {string} key to id * @param {*} value value to store @@ -19,4 +24,7 @@ const getter = key => { return cache.get(key) } -module.exports = { setter, getter } +export { + setter, + getter +} diff --git a/packages/@jsonql/koa/src/utils/index.js b/packages/@jsonql/koa/src/utils/index.js index 988bb80d7083a5921542b0877079e3f79b5e44fd..23ab40175e846828a5bd472b3e1d1e5340a509da 100644 --- a/packages/@jsonql/koa/src/utils/index.js +++ b/packages/@jsonql/koa/src/utils/index.js @@ -1,13 +1,52 @@ -// the utils methods export -const processJwtKeys = require('./config-check/process-jwt-keys') -const { createTokenValidator } = require('jsonql-jwt') +// Just group all the imports here then export them in one go +import processJwtKeys from '../options/process-jwt-keys' +import { createTokenValidator } from 'jsonql-jwt' +import { isObject, isArray } from 'jsonql-params-validator' -const { +import { getDebug } from './utils' +import { + isKeyInObject, chainFns, - inArray, + headerParser, + getDocLen, + packResult, + printError, + forbiddenHandler, + ctxErrorHandler, + + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + + getCallMethod, + isHeaderPresent, + + isNotEmpty, + isContract, + handleOutput, + extractArgsFromPayload, + getNameFromPayload, + + extractParamsFromContract, + + getQueryFromPayload, + getMutationFromPayload +} from 'jsonql-utils' + +// export +export { + processJwtKeys, + createTokenValidator, + getDebug, + isObject, + isArray, + + isKeyInObject, + chainFns, + inArray, headerParser, getDocLen, packResult, @@ -22,12 +61,13 @@ const { getCallMethod, isHeaderPresent, - isObject, isNotEmpty, - isContractJson, + isContract, handleOutput, extractArgsFromPayload, getNameFromPayload, - extractParamsFromContract -} = require('./utils') + extractParamsFromContract, + getQueryFromPayload, + getMutationFromPayload +} diff --git a/packages/@jsonql/koa/src/utils/utils.js b/packages/@jsonql/koa/src/utils/utils.js index 37b1331877e1c1b9eca6071a532b51df6257c95c..40313baf54fe1026900897f9a6b11eadba3787b6 100644 --- a/packages/@jsonql/koa/src/utils/utils.js +++ b/packages/@jsonql/koa/src/utils/utils.js @@ -1,393 +1,10 @@ -// util methods -const _ = require('lodash') -const { join } = require('path') -const fs = require('fs') -const { inspect } = require('util') -const { isObject } = require('jsonql-params-validator') -const jsonqlErrors = require('jsonql-errors') -const { - JsonqlResolverNotFoundError, - getErrorByStatus, - JsonqlError -} = jsonqlErrors; -const { - BASE64_FORMAT, - CONTENT_TYPE, - QUERY_NAME, - MUTATION_NAME, - API_REQUEST_METHODS, - PAYLOAD_PARAM_NAME, - CONDITION_PARAM_NAME, - RESOLVER_PARAM_NAME , - QUERY_ARG_NAME -} = require('jsonql-constants') -const { trim } = _; +// All of the functions here we moved to jsonql-utils +import { getDebug as _getDebug } from 'jsonql-utils' +const MODULE_NAME = 'jsonql-koa' // just keep the old name -// export a create debug method -const debug = require('debug') -/** - * @param {string} name for id - * @param {boolean} cond i.e. NODE_ENV==='development' - * @return {void} nothing - */ -const getDebug = (name, cond = true) => ( - cond ? debug('jsonql-koa').extend(name) : () => {} -) +const getDebug = (name) => _getDebug(name, MODULE_NAME) -/** - * using lodash to chain two functions - * @param {function} mainFn function - * @param {array} ...moreFns functions spread - * @return {function} to accept the parameter for the first function - */ -const chainFns = (mainFn, ...moreFns) => ( - (...args) => { - let chain = _( Reflect.apply(mainFn, null, args) ).chain() - let ctn = moreFns.length; - for (let i = 0; i < ctn; ++i) { - chain = chain.thru(moreFns[i]) - } - return chain.value() - } -) - -/** - * DIY in Array - * @param {array} arr to check from - * @param {*} value to check against - * @return {boolean} true on found - */ -const inArray = (arr, value) => !!arr.filter(a => a === value).length; - -/** - * From underscore.string library - * @BUG there is a bug here with the non-standard name start with _ - * @param {string} str string - * @return {string} dasherize string - */ -const dasherize = str => ( - trim(str) - .replace(/([A-Z])/g, '-$1') - .replace(/[-_\s]+/g, '-') - .toLowerCase() -) - -/** - * Get document (string) byte length for use in header - * @param {string} doc to calculate - * @return {number} length - */ -const getDocLen = doc => Buffer.byteLength(doc, 'utf8') - -/** - * The koa ctx object is not returning what it said on the documentation - * So I need to write a custom parser to check the request content-type - * @param {object} req the ctx.request - * @param {string} type (optional) to check against - * @return {mixed} Array or Boolean - */ -const headerParser = (req, type) => { - try { - const headers = req.headers.accept.split(',') - if (type) { - return headers.filter(h => h === type) - } - return headers; - } catch (e) { - // When Chrome dev tool activate the headers become empty - return []; - } -} - -/** - * wrapper of above method to make it easier to use - * @param {object} req ctx.request - * @param {string} type of header - * @return {boolean} - */ -const isHeaderPresent = (req, type) => { - const headers = headerParser(req, type) - return !!headers.length; -} - -/** - * @TODO need to be more flexible - * @param {object} ctx koa - * @param {object} opts configuration - * @return {boolean} if it match - */ -const isJsonqlPath = (ctx, opts) => ctx.path === opts.jsonqlPath; - -/** - * combine two check in one and save time - * @param {object} ctx koa - * @param {object} opts config - * @return {boolean} check result - */ -const isJsonqlRequest = (ctx, opts) => { - const header = isHeaderPresent(ctx.request, opts.contentType) - if (header) { - return isJsonqlPath(ctx, opts) - } - return false; -} - -/** - * check if this is point to the jsonql console - * @param {object} ctx koa context - * @param {object} opts config - * @return {boolean} - */ -const isJsonqlConsoleUrl = (ctx, opts) => ( - ctx.method === 'GET' && isJsonqlPath(ctx, opts) -) - -/** - * getting what is calling after the above check - * @param {string} method of call - * @return {mixed} false on failed - */ -const getCallMethod = method => { - const [ POST, PUT ] = API_REQUEST_METHODS; - switch (true) { - case method === POST: - return QUERY_NAME; - case method === PUT: - return MUTATION_NAME; - default: - return false; - } -}; - -/** - * @param {string} name - * @param {string} type - * @param {object} opts - * @return {function} - */ -const getPathToFn = function(name, type, opts) { - const dir = opts.resolverDir; - const fileName = dasherize(name); - let paths = []; - if (opts.contract && opts.contract[type] && opts.contract[type].path) { - paths.push(opts.contract[type].path); - } - paths.push( join(dir, type, fileName, 'index.js') ) - paths.push( join(dir, type, fileName + '.js') ) - // paths.push( join(dir, fileName + '.js') ); - const ctn = paths.length; - for (let i=0; i { - return JSON.stringify({ data: result }) -} - -/** - * Handle the output - * @param {object} opts configuration - * @return {function} with ctx and body as params - */ -const handleOutput = function(opts) { - return function(ctx, body) { - ctx.size = getDocLen(body) - ctx.type = opts.contentType; - ctx.status = 200; - ctx.body = body; - } +export { + getDebug } - -/** - * handle HTML output for the web console - * @param {object} ctx koa context - * @param {string} body output content - * @return {void} - */ -const handleHtmlOutput = function(ctx, body) { - ctx.size = getDocLen(body) - ctx.type = 'text/html'; - ctx.status = 200; - ctx.body = body + ''; // just make sure its string output -} - -/** - * Port this from the CIS App - * @param {string} key of object - * @param {mixed} value of object - * @return {string} of things we after - */ -const replaceErrors = function(key, value) { - if (value instanceof Error) { - var error = {}; - Object.getOwnPropertyNames(value).forEach(function (key) { - error[key] = value[key]; - }) - return error; - } - return value; -} - -/** - * create readible string version of the error object - * @param {object} error obj - * @return {string} printable result - */ -const printError = function(error) { - //return 'MASKED'; //error.toString(); - // return JSON.stringify(error, replaceErrors); - return inspect(error, false, null, true) -} - -/** - * wrapper method - the output is trying to match up the structure of the Error sub class - * @param {mixed} detail of fn error - * @param {string} [className=JsonqlError] the errorName - * @param {number} [statusCode=500] the original error code - * @return {string} stringify error - */ -const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { - return JSON.stringify({ - error: { detail, className, statusCode, message } - }) -} - -/** - * use the ctx to generate error output - * V1.1.0 we render this as a normal output with status 200 - * then on the client side will check against the result object for error - * @param {object} ctx context - * @param {number} code 404 / 500 etc - * @param {object} e actual error - * @param {string} message if there is one - * @param {string} name custom error class name - */ -const ctxErrorHandler = function(ctx, code, e, message = '') { - const render = handleOutput({contentType: CONTENT_TYPE}) - let name; - if (typeof code === 'string') { - name = code; - code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1; - } else { - name = jsonqlErrors.getErrorByStatus(code) - } - // preserve the message - if (!message && e && e.message) { - message = e.message; - } - return render(ctx, packError(e, name, code, message)) -} - -/** - * Just a wrapper to be clearer what error is it - * @param {object} ctx koa - * @param {object} e error - * @return {undefined} nothing - */ -const forbiddenHandler = (ctx, e) => ( - ctxErrorHandler(ctx, 403, e, 'JsonqlAuthorisationError') -) - -/** - * Like what the name said - * @param {object} contract the contract json - * @param {string} type query|mutation - * @param {string} name of the function - * @return {object} the params part of the contract - */ -const extractParamsFromContract = function(contract, type, name) { - try { - const result = contract[type][name]; - debug('extractParamsFromContract', result) - if (!result) { - debug(name, type, contract) - throw new JsonqlResolverNotFoundError(name, type) - } - return result; - } catch(e) { - throw new JsonqlResolverNotFoundError(name, e) - } -} - -/** - * Check several parameter that there is something in the param - * @param {*} param input - * @return {boolean} - */ -const isNotEmpty = function(param) { - return param !== undefined && param !== false && param !== null && trim(param) !== ''; -} - -/** - * Check if a json file is a contract or not - * @param {*} contract input - * @return {*} false on failed - */ -const isContractJson = (contract) => ( - isObject(contract) && (contract[QUERY_NAME] || contract[MUTATION_NAME]) ? contract : false -) - -/** - * Extract the args from the payload - * @param {object} payload to work with - * @param {string} type of call - * @return {array} args - */ -const extractArgsFromPayload = function(payload, type) { - switch (type) { - case QUERY_NAME: - return payload[QUERY_ARG_NAME]; - case MUTATION_NAME: - return [ - payload[PAYLOAD_PARAM_NAME], - payload[CONDITION_PARAM_NAME] - ]; - default: - throw new JsonqlError(`Unknown ${type} to extract argument from!`); - } -} - -// export -module.exports = { - - chainFns, - - inArray, - getDebug, - - dasherize, - headerParser, - getPathToFn, - getDocLen, - packResult, - packError, - printError, - ctxErrorHandler, - forbiddenHandler, - - isJsonqlPath, - isJsonqlRequest, - isJsonqlConsoleUrl, - - getCallMethod, - isHeaderPresent, - extractParamsFromContract, - - isObject, - isNotEmpty, - isContractJson, - - handleOutput, - handleHtmlOutput, - extractArgsFromPayload -}; diff --git a/packages/@jsonql/koa/tests/chain-fn.test.js b/packages/@jsonql/koa/tests/chain-fn.test.js deleted file mode 100644 index 7c8962e07b9d2fa6bdad3b07e526bc4108c53361..0000000000000000000000000000000000000000 --- a/packages/@jsonql/koa/tests/chain-fn.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// testing just one function chainFns -const test = require('ava') -const { chainFns } = require('../src/lib') - - -test('It should able to accept more than one functions after the first one', t => { - - const baseFn = (num) => num * 10; - const add1 = (num) => num + 1; - const add2 = (num) => num + 2; - - const fn = chainFns(baseFn, add1, add2) - - const result = fn(10) - - t.is(103, result) - -}) diff --git a/packages/@jsonql/koa/tests/config.test.js b/packages/@jsonql/koa/tests/config.test.js index f9ea2ac14d125704f74e9ac176cf56668157ed71..d4ad7913294543b48dbd2a1cbeeb258b1827c6ae 100644 --- a/packages/@jsonql/koa/tests/config.test.js +++ b/packages/@jsonql/koa/tests/config.test.js @@ -2,9 +2,13 @@ const test = require('ava') const fsx = require('fs-extra') const { join, resolve } = require('path') -const configCheck = require('../src/lib/config-check') -const { processJwtKeys } = require('../src/lib') -const { jwtProcessKey } = require('../src/lib/config-check/options') + +const { configCheck } = require('../src/options') +const processJwtKeysDefault = require('../src/options/process-jwt-keys') +const processJwtKeys = processJwtKeysDefault.default + +const { jwtProcessKey } = require('../src/options/options') + const debug = require('debug')('jsonql-koa:test:config') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'config-test') diff --git a/packages/@jsonql/koa/tests/contract.test.js b/packages/@jsonql/koa/tests/contract.test.js index 40b2466d0d30dca5a56b3635ff82f14aadb1509f..5aa4beb14bccea1fee40ded4d470c10aacd09997 100644 --- a/packages/@jsonql/koa/tests/contract.test.js +++ b/packages/@jsonql/koa/tests/contract.test.js @@ -2,14 +2,14 @@ const test = require('ava') const { join } = require('path') const fsx = require('fs-extra') -const generator = require('../src/lib/contract-generator') -const { isContractJson } = require('../src/lib') +const { contractGenerator } = require('../src/contracts/contract-generator') +const { isContract } = require('jsonql-utils') const debug = require('debug')('jsonql-koa:test:gen') const contractDir = join(__dirname, 'fixtures', 'tmp', 'generator') const resolverDir = join(__dirname, 'fixtures', 'resolvers') test.before(t => { - t.context.initContract = generator({ + t.context.initContract = contractGenerator({ contractDir, resolverDir, returnAs: 'json' @@ -24,5 +24,5 @@ test('It should able to generate a contract file', async t => { // this way can test if this setup works for the middleware as well const contract = await t.context.initContract; debug(contract) - t.truthy(isContractJson(contract)) + t.truthy(isContract(contract)) }) diff --git a/packages/@jsonql/koa/src/middlewares/errors-handler-middleware.js b/packages/@jsonql/koa/tests/fixtures/unused/errors-handler-middleware.js similarity index 100% rename from packages/@jsonql/koa/src/middlewares/errors-handler-middleware.js rename to packages/@jsonql/koa/tests/fixtures/unused/errors-handler-middleware.js diff --git a/packages/@jsonql/koa/tests/helpers/browser.js b/packages/@jsonql/koa/tests/helpers/browser.js index b6217f2a40020d89764ab55c5d4c1bbf327dec42..bdabdc3bf6deb6f25af61e843360fba2a22a76af 100644 --- a/packages/@jsonql/koa/tests/helpers/browser.js +++ b/packages/@jsonql/koa/tests/helpers/browser.js @@ -2,7 +2,7 @@ const serverIoCore = require('server-io-core') const { join } = require('path') -const jsonqlKoa = require('../../') +const jsonqlKoa = require('../../main') const baseDir = join(__dirname, '..', 'fixtures') diff --git a/packages/@jsonql/koa/tests/helpers/server.js b/packages/@jsonql/koa/tests/helpers/server.js index 2c20f0697608662097b90e6280cb5dd2edeac600..4c69beac390017230e93199b4a404d3b09571be4 100644 --- a/packages/@jsonql/koa/tests/helpers/server.js +++ b/packages/@jsonql/koa/tests/helpers/server.js @@ -3,19 +3,20 @@ const Koa = require('koa') const { join } = require('path') const bodyparser = require('koa-bodyparser') -const jsonqlMiddleware = require(join(__dirname, '..', '..','index')) +const jsonqlKoa = require('../../main') +console.info(jsonqlKoa) const { type, headers, dirs } = require('../fixtures/options') const fsx = require('fs-extra') const myKey = '4670994sdfkl'; // add a dir to seperate the contract files module.exports = (config={}, dir = '') => { - const app = new Koa(); - app.use(bodyparser()); - app.use(jsonqlMiddleware( + const app = new Koa() + app.use(bodyparser()) + app.use(jsonqlKoa.default( Object.assign({},{ resolverDir: dirs.resolverDir, contractDir: join(dirs.contractDir, dir) }, config) - )); + )) return app; } diff --git a/packages/@jsonql/koa/tests/helpers/sub-server.js b/packages/@jsonql/koa/tests/helpers/sub-server.js index aef5991064f15350a6b66c678c98c9c78fb559d7..29bd9b87f1224a6ed4f5ff43224cb28d2d093e97 100644 --- a/packages/@jsonql/koa/tests/helpers/sub-server.js +++ b/packages/@jsonql/koa/tests/helpers/sub-server.js @@ -2,7 +2,7 @@ const { join } = require('path') const fixturesDir = join(__dirname, '..', 'fixtures') const serverIoCore = require('server-io-core') -const jsonqlKoa = require('../../index') +const jsonqlKoa = require('../../main') function startSubServer(msPort) { return serverIoCore({ diff --git a/packages/@jsonql/koa/tests/koa.test.js b/packages/@jsonql/koa/tests/koa.test.js index 037f90b9512c8b7cf3bf295ff8e408a9fb97e3b0..9b3fee2f8c2a048f2091b2726a208883cc0514e5 100644 --- a/packages/@jsonql/koa/tests/koa.test.js +++ b/packages/@jsonql/koa/tests/koa.test.js @@ -1,3 +1,4 @@ +// Koa basic test const test = require('ava') const { SHOW_CONTRACT_DESC_PARAM } = require('jsonql-constants') diff --git a/packages/contract-cli/cli.js b/packages/contract-cli/cli.js index c2428f7f7108c3edda4bf9c27c354e868d94362c..638c1fb42dd7c7ee4ab901dcd8bf8c1c65bd7faa 100755 --- a/packages/contract-cli/cli.js +++ b/packages/contract-cli/cli.js @@ -11,7 +11,7 @@ const { getPaths, checkFile, watcher -} = require('./lib') +} = require('./src') const { KEY_WORD } = require('jsonql-constants') const { join } = require('path') const debug = require('debug')('jsonql-contract:cli') diff --git a/packages/contract-cli/index.js b/packages/contract-cli/index.js index c5146a0b2aafc16854358e1400a7d64ef6d0fc54..b0550b71b05e53737ba174f9dc22c99145a7844b 100755 --- a/packages/contract-cli/index.js +++ b/packages/contract-cli/index.js @@ -4,7 +4,7 @@ const { generator, getPaths, watcher -} = require('./lib') +} = require('./src') const { KEY_WORD } = require('jsonql-constants') // const debug = require('debug')('jsonql-contract:api'); // main contract-cli @api public diff --git a/packages/contract-cli/package.json b/packages/contract-cli/package.json index 03b10e5089c147852ccdfb973b0e278e95819ac2..746df99a4f4d5be9d8d28f989f06ca823236cb3d 100755 --- a/packages/contract-cli/package.json +++ b/packages/contract-cli/package.json @@ -1,10 +1,10 @@ { "name": "jsonql-contract", - "version": "1.7.8", + "version": "1.7.9", "description": "JS API / command line tool to generate the contract.json for jsonql", "main": "index.js", "files": [ - "lib", + "src", "cli.js", "index.js" ], @@ -39,22 +39,22 @@ }, "dependencies": { "acorn": "^7.0.0", - "chokidar": "^3.0.2", + "debug": "^4.1.1", + "chokidar": "^3.1.0", "colors": "^1.3.3", "fs-extra": "^8.1.0", "glob": "^7.1.4", "jsdoc-api": "^5.0.3", - "jsonql-constants": "^1.8.2", - "jsonql-errors": "^1.1.2", - "jsonql-params-validator": "^1.4.6", - "jsonql-utils": "^0.4.6", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.6.10", "kefir": "^3.8.6", "lodash": "^4.17.15", "yargs": "^14.0.0" }, "devDependencies": { - "ava": "^2.3.0", - "debug": "^4.1.1", + "ava": "^2.4.0", "nyc": "^14.1.1", "request": "^2.88.0" }, diff --git a/packages/contract-cli/lib/ast/acorn.js b/packages/contract-cli/src/ast/acorn.js similarity index 100% rename from packages/contract-cli/lib/ast/acorn.js rename to packages/contract-cli/src/ast/acorn.js diff --git a/packages/contract-cli/lib/ast/index.js b/packages/contract-cli/src/ast/index.js similarity index 100% rename from packages/contract-cli/lib/ast/index.js rename to packages/contract-cli/src/ast/index.js diff --git a/packages/contract-cli/lib/ast/jsdoc.js b/packages/contract-cli/src/ast/jsdoc.js similarity index 100% rename from packages/contract-cli/lib/ast/jsdoc.js rename to packages/contract-cli/src/ast/jsdoc.js diff --git a/packages/contract-cli/lib/generator/es-extra.js b/packages/contract-cli/src/generator/es-extra.js similarity index 100% rename from packages/contract-cli/lib/generator/es-extra.js rename to packages/contract-cli/src/generator/es-extra.js diff --git a/packages/contract-cli/lib/generator/files.js b/packages/contract-cli/src/generator/files.js similarity index 100% rename from packages/contract-cli/lib/generator/files.js rename to packages/contract-cli/src/generator/files.js diff --git a/packages/contract-cli/lib/generator/get-resolver.js b/packages/contract-cli/src/generator/get-resolver.js similarity index 100% rename from packages/contract-cli/lib/generator/get-resolver.js rename to packages/contract-cli/src/generator/get-resolver.js diff --git a/packages/contract-cli/lib/generator/helpers.js b/packages/contract-cli/src/generator/helpers.js similarity index 100% rename from packages/contract-cli/lib/generator/helpers.js rename to packages/contract-cli/src/generator/helpers.js diff --git a/packages/contract-cli/lib/generator/import.template.js b/packages/contract-cli/src/generator/import.template.js similarity index 100% rename from packages/contract-cli/lib/generator/import.template.js rename to packages/contract-cli/src/generator/import.template.js diff --git a/packages/contract-cli/lib/generator/index.js b/packages/contract-cli/src/generator/index.js similarity index 100% rename from packages/contract-cli/lib/generator/index.js rename to packages/contract-cli/src/generator/index.js diff --git a/packages/contract-cli/lib/get-paths.js b/packages/contract-cli/src/get-paths.js similarity index 100% rename from packages/contract-cli/lib/get-paths.js rename to packages/contract-cli/src/get-paths.js diff --git a/packages/contract-cli/lib/index.js b/packages/contract-cli/src/index.js similarity index 100% rename from packages/contract-cli/lib/index.js rename to packages/contract-cli/src/index.js diff --git a/packages/contract-cli/lib/options.js b/packages/contract-cli/src/options.js similarity index 100% rename from packages/contract-cli/lib/options.js rename to packages/contract-cli/src/options.js diff --git a/packages/contract-cli/lib/public-contract/hello-world.json b/packages/contract-cli/src/public-contract/hello-world.json similarity index 100% rename from packages/contract-cli/lib/public-contract/hello-world.json rename to packages/contract-cli/src/public-contract/hello-world.json diff --git a/packages/contract-cli/lib/public-contract/index.js b/packages/contract-cli/src/public-contract/index.js similarity index 100% rename from packages/contract-cli/lib/public-contract/index.js rename to packages/contract-cli/src/public-contract/index.js diff --git a/packages/contract-cli/lib/utils.js b/packages/contract-cli/src/utils.js similarity index 93% rename from packages/contract-cli/lib/utils.js rename to packages/contract-cli/src/utils.js index 4cf69bdaa97e9ea9f1adbdef250a163ca142f026..71322c6c658b301889c16481e30d2687f64f199f 100644 --- a/packages/contract-cli/lib/utils.js +++ b/packages/contract-cli/src/utils.js @@ -2,18 +2,21 @@ const fsx = require('fs-extra') const { join, extname, resolve } = require('path') const { isObject } = require('jsonql-params-validator') -// const { KEY_WORD } = require('jsonql-constants'); -const checkOptions = require('./options') // we keep the lodash reference for chain later const { transform } = require('lodash') +const debug = require('debug') +// const { KEY_WORD } = require('jsonql-constants'); +const checkOptions = require('./options') const { JsonqlError } = require('jsonql-errors') // timestamp with mil seconds -const { timestamp, getDebug } = require('jsonql-utils') +const { timestamp } = require('jsonql-utils') const MODULE_NAME = 'jsonql-contract' const getTimestamp = () => timestamp(true) -const debug = getDebug('utils', MODULE_NAME) +const getDebug = (name) => debug(MODULE_NAME).extend(name) + + /** * check if there is a config file and use that value instead @@ -76,7 +79,7 @@ const getConfigFromArgs = (config, cmd) => ( const applyDefaultOptions = (config, cmd = false) => ( getConfigFromArgs(config, cmd) .then(config => { - debug('show config', config) + getDebug('applyDefaultOptions')('show config', config) if (config.public === 'true' || config.public === 1 || config.public === '1') { config.public = true; // because it might be a string true } @@ -112,5 +115,5 @@ module.exports = { getTimestamp, checkFile, applyDefaultOptions, - getDebug: (name) => getDebug(name, MODULE_NAME) + getDebug } diff --git a/packages/contract-cli/lib/watcher/index.js b/packages/contract-cli/src/watcher/index.js similarity index 100% rename from packages/contract-cli/lib/watcher/index.js rename to packages/contract-cli/src/watcher/index.js diff --git a/packages/contract-cli/lib/watcher/run.js b/packages/contract-cli/src/watcher/run.js similarity index 100% rename from packages/contract-cli/lib/watcher/run.js rename to packages/contract-cli/src/watcher/run.js diff --git a/packages/contract-cli/lib/watcher/socket.js b/packages/contract-cli/src/watcher/socket.js similarity index 100% rename from packages/contract-cli/lib/watcher/socket.js rename to packages/contract-cli/src/watcher/socket.js diff --git a/packages/contract-cli/lib/watcher/watcher.js b/packages/contract-cli/src/watcher/watcher.js similarity index 100% rename from packages/contract-cli/lib/watcher/watcher.js rename to packages/contract-cli/src/watcher/watcher.js diff --git a/packages/contract-cli/tests/contract-with-doc.test.js b/packages/contract-cli/tests/contract-with-doc.test.js index 8ffb5e6f5158fbcaabb7ef97078bc41b9e1318eb..96ed8a88e9f158b9e5c79fbbe0c5f9af85acc82f 100644 --- a/packages/contract-cli/tests/contract-with-doc.test.js +++ b/packages/contract-cli/tests/contract-with-doc.test.js @@ -2,7 +2,7 @@ const test = require('ava') const { join } = require('path') const { inspect } = require('util') -const { generator } = require('../lib') +const generator = require('../index') const resolverDir = join(__dirname, 'fixtures', 'resolvers') const contractDir = join(__dirname, 'fixtures', 'tmp', 'doc') const debug = require('debug')('jsonql-contract:test:generator') @@ -10,14 +10,14 @@ const fsx = require('fs-extra') const baseContractFile = join(contractDir, 'contract.json') const publicContractFile = join(contractDir, 'public-contract.json') const { DEFAULT_TYPE } = require('jsonql-constants') -const checkConfig = require('../lib/options') +const checkConfig = require('../src/options') test.before(async t => { - const options = await checkConfig({ + const options = { resolverDir, contractDir, enableAuth: true - }) + } const result = await generator(options) t.context.contract = fsx.readJsonSync( baseContractFile ) }) diff --git a/packages/contract-cli/tests/paths.test.js b/packages/contract-cli/tests/paths.test.js index 14b065f49655c8d74b5fb59f8d85d0b3ad38e152..8508450f39831e2fa1fe451ee1f4d09f1bff4eba 100755 --- a/packages/contract-cli/tests/paths.test.js +++ b/packages/contract-cli/tests/paths.test.js @@ -1,6 +1,6 @@ const test = require('ava') const { join } = require('path') -const { getPaths } = require('../lib') +const { getPaths } = require('../src') const dir = join(__dirname, 'fixtures', 'resolvers') const debug = require('debug')('jsonql-contract:test:paths') diff --git a/packages/http-client/src/lib/utils.js b/packages/http-client/src/lib/utils.js index 08e8bd8c137c8df2519de645439e508f5a7445bc..dd401e905208d9d56d5cfb2805410b94067858ae 100644 --- a/packages/http-client/src/lib/utils.js +++ b/packages/http-client/src/lib/utils.js @@ -43,17 +43,7 @@ export const cacheBurstUrl = url => urlParams(url, cacheBurst()) export const cacheBurst = () => ({ _cb: timestamp() }) -/** - * @param {object} jsonqlInstance the init instance of jsonql client - * @param {object} contract the static contract - * @return {object} contract may be from server - */ -export const getContractFromConfig = function(jsonqlInstance, contract = {}) { - if (isJsonqlContract(contract)) { - return Promise.resolve(contract) - } - return jsonqlInstance.getContract() -} + /** * handle the return data diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index bc37540bbd6d0df5b47a3c4b57d8efb5fb805fe2..70d2eff34a1a9bda5826db33abff579f6c93829c 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1 +1,2 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlJwt={},t.debug)}(this,function(t,r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function n(t){this.message=t}n.prototype=new Error,n.prototype.name="InvalidCharacterError";var o="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var r=String(t).replace(/=+$/,"");if(r.length%4==1)throw new n("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,i,u=0,a=0,f="";i=r.charAt(a++);~i&&(o=u%4?64*o+i:i,u++%4)?f+=String.fromCharCode(255&o>>(-2*u&6)):0)i=e.indexOf(i);return f};var i=function(t){var r=t.replace(/-/g,"+").replace(/_/g,"/");switch(r.length%4){case 0:break;case 2:r+="==";break;case 3:r+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(o(t).replace(/(.)/g,function(t,r){var e=r.charCodeAt(0).toString(16).toUpperCase();return e.length<2&&(e="0"+e),"%"+e}))}(r)}catch(t){return o(r)}};function u(t){this.message=t}u.prototype=new Error,u.prototype.name="InvalidTokenError";var a=function(t,r){if("string"!=typeof t)throw new u("Invalid token specified");var e=!0===(r=r||{}).header?0:1;try{return JSON.parse(i(t.split(".")[e]))}catch(t){throw new u("Invalid token specified: "+t.message)}},f=u;a.InvalidTokenError=f;var c="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},s="object"==typeof c&&c&&c.Object===Object&&c,h="object"==typeof self&&self&&self.Object===Object&&self,l=s||h||Function("return this")(),p=l.Symbol,v=Object.prototype,g=v.hasOwnProperty,y=v.toString,d=p?p.toStringTag:void 0;var b=Object.prototype.toString;var w="[object Null]",_="[object Undefined]",m=p?p.toStringTag:void 0;function j(t){return null==t?void 0===t?_:w:m&&m in Object(t)?function(t){var r=g.call(t,d),e=t[d];try{t[d]=void 0;var n=!0}catch(t){}var o=y.call(t);return n&&(r?t[d]=e:delete t[d]),o}(t):function(t){return b.call(t)}(t)}function A(t){return null!=t&&"object"==typeof t}var E="[object Symbol]";function O(t){return"symbol"==typeof t||A(t)&&j(t)==E}function P(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e0){if(++ut>=et)return arguments[0]}else ut=0;return it.apply(void 0,arguments)});function st(t){return t!=t}function ht(t,r,e){return r==r?function(t,r,e){for(var n=e-1,o=t.length;++n-1&&t%1==0&&t-1&&t%1==0&&t<=mt}function At(t){return null!=t&&jt(t.length)&&!D(t)}var Et=Object.prototype;function Ot(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||Et)}var Pt="[object Arguments]";function Rt(t){return A(t)&&j(t)==Pt}var Tt=Object.prototype,St=Tt.hasOwnProperty,Ut=Tt.propertyIsEnumerable,Bt=Rt(function(){return arguments}())?Rt:function(t){return A(t)&&St.call(t,"callee")&&!Ut.call(t,"callee")};var kt="object"==typeof t&&t&&!t.nodeType&&t,It=kt&&"object"==typeof module&&module&&!module.nodeType&&module,xt=It&&It.exports===kt?l.Buffer:void 0,Ct=(xt?xt.isBuffer:void 0)||function(){return!1},Yt={};Yt["[object Float32Array]"]=Yt["[object Float64Array]"]=Yt["[object Int8Array]"]=Yt["[object Int16Array]"]=Yt["[object Int32Array]"]=Yt["[object Uint8Array]"]=Yt["[object Uint8ClampedArray]"]=Yt["[object Uint16Array]"]=Yt["[object Uint32Array]"]=!0,Yt["[object Arguments]"]=Yt["[object Array]"]=Yt["[object ArrayBuffer]"]=Yt["[object Boolean]"]=Yt["[object DataView]"]=Yt["[object Date]"]=Yt["[object Error]"]=Yt["[object Function]"]=Yt["[object Map]"]=Yt["[object Number]"]=Yt["[object Object]"]=Yt["[object RegExp]"]=Yt["[object Set]"]=Yt["[object String]"]=Yt["[object WeakMap]"]=!1;var Mt="object"==typeof t&&t&&!t.nodeType&&t,Dt=Mt&&"object"==typeof module&&module&&!module.nodeType&&module,Lt=Dt&&Dt.exports===Mt&&s.process,zt=function(){try{var t=Dt&&Dt.require&&Dt.require("util").types;return t||Lt&&Lt.binding&&Lt.binding("util")}catch(t){}}(),Nt=zt&&zt.isTypedArray,Ft=Nt?function(t){return function(r){return t(r)}}(Nt):function(t){return A(t)&&jt(t.length)&&!!Yt[j(t)]},Vt=Object.prototype.hasOwnProperty;function $t(t,r){var e=R(t),n=!e&&Bt(t),o=!e&&!n&&Ct(t),i=!e&&!n&&!o&&Ft(t),u=e||n||o||i,a=u?function(t,r){for(var e=-1,n=Array(t);++e-1},cr.prototype.set=function(t,r){var e=this.__data__,n=ar(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this};var sr=K(l,"Map");function hr(t,r){var e,n,o=t.__data__;return("string"==(n=typeof(e=r))||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?o["string"==typeof r?"string":"hash"]:o.map}function lr(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r=n?t:function(t,r,e){var n=-1,o=t.length;r<0&&(r=-r>o?0:o+r),(e=e>o?o:e)<0&&(e+=o),o=r>e?0:e-r>>>0,r>>>=0;for(var i=Array(o);++na))return!1;var c=i.get(t);if(c&&i.get(r))return c==r;var s=-1,h=!0,l=e&me?new be:void 0;for(i.set(t,r),i.set(r,t);++s1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=An.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!k(e))return!1;var n=typeof r;return!!("number"==n?At(e)&&vt(r,e.length):"string"==n&&r in e)&&yt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++e-1;);return e}(n,o),function(t,r){for(var e=t.length;e--&&ht(r,t[e],0)>-1;);return e}(n,o)+1).join("")}function Bn(t){return!!R(t)||null!=t&&""!==Un(t)}var kn=function(t){return!dn(t)&&!_n(parseFloat(t))},In=function(t){return""!==Un(t)&&dn(t)},xn=function(t){return function(t){return!0===t||!1===t||A(t)&&j(t)==bn}(t)},Cn=function(t,r){return void 0===r&&(r=!0),!mn(t)&&""!==t&&""!==Un(t)&&(!1===r||!0===r&&!function(t){return null===t}(t))},Yn="type",Mn="optional",Dn="enumv",Ln="args",zn="checker",Nn="alias",Fn=Yn,Vn=Mn,$n=Dn,qn=Ln,Jn=zn,Wn=Nn,Gn="continue",Hn=function(t){switch(t){case"number":return kn;case"string":return In;case"boolean":return xn;default:return Cn}},Zn=function(t,r){return void 0===r&&(r=""),!!R(t)&&(""===r||""===Un(r)||!(t.filter(function(t){return!Hn(r)(t)}).length>0))},Kn=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},Qn=function(t,r){var e=t.arg;return r.length>1?!e.filter(function(t){return!(r.length>r.filter(function(r){return!Hn(r)(t)}).length)}).length:r.length>r.filter(function(t){return!Zn(e,t)}).length},Xn=function(t,r){if(void 0===r&&(r=null),kr(t)){if(!r)return!0;if(Zn(r))return!r.filter(function(r){var e=t[r.name];return!(r.type.length>r.type.filter(function(t){var r;return!!mn(e)||(!1!==(r=Kn(t))?!Qn({arg:e},r):!Hn(t)(e))}).length)}).length}return!1},to=function(){try{if(window||document)return!0}catch(t){}return!1},ro=function(){try{if(!to()&&c)return!0}catch(t){}return!1};var eo=function(t){function r(){for(var r=[],e=arguments.length;e--;)r[e]=arguments[e];t.apply(this,r)}return t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r,r.where=function(){return to()?"browser":ro()?"node":"unknown"},r}(Error),no=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(r,e),r}(Error),oo=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(r,e),r}(Error),io=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(r,e),r}(Error),uo=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,Error.captureStackTrace&&Error.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return-1},Object.defineProperties(r,e),r}(eo);function ao(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}var fo=function(t,r){var e,n,o,i,u;switch(!0){case"object"===t:return o=(n=r).arg,i=n.param,u=[o],Array.isArray(i.keys)&&i.keys.length&&u.push(i.keys),!Xn.apply(null,u);case"array"===t:return!Zn(r.arg);case!1!==(e=Kn(t)):return!Qn(r,e);default:return!Hn(t)(r.arg)}},co=function(t,r){return mn(t)?!0!==r.optional||mn(r.defaultvalue)?null:r.defaultvalue:t},so=function(t,r){var e,n=Object.keys(t);return e=r,!!n.filter(function(t){return t===e}).length},ho=function(t){void 0===t&&(t=!1);var r=Date.now();return t?Math.floor(r/1e3):r},lo=[],po=[],vo="undefined"!=typeof Uint8Array?Uint8Array:Array,go=!1;function yo(){go=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,e=t.length;r>18&63]+lo[o>>12&63]+lo[o>>6&63]+lo[63&o]);return i.join("")}function wo(t){var r;go||yo();for(var e=t.length,n=e%3,o="",i=[],u=0,a=e-n;ua?a:u+16383));return 1===n?(r=t[e-1],o+=lo[r>>2],o+=lo[r<<4&63],o+="=="):2===n&&(r=(t[e-2]<<8)+t[e-1],o+=lo[r>>10],o+=lo[r>>4&63],o+=lo[r<<2&63],o+="="),i.push(o),i.join("")}function _o(t,r,e,n,o){var i,u,a=8*o-n-1,f=(1<>1,s=-7,h=e?o-1:0,l=e?-1:1,p=t[r+h];for(h+=l,i=p&(1<<-s)-1,p>>=-s,s+=a;s>0;i=256*i+t[r+h],h+=l,s-=8);for(u=i&(1<<-s)-1,i>>=-s,s+=n;s>0;u=256*u+t[r+h],h+=l,s-=8);if(0===i)i=1-c;else{if(i===f)return u?NaN:1/0*(p?-1:1);u+=Math.pow(2,n),i-=c}return(p?-1:1)*u*Math.pow(2,i-n)}function mo(t,r,e,n,o,i){var u,a,f,c=8*i-o-1,s=(1<>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:i-1,v=n?1:-1,g=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,u=s):(u=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-u))<1&&(u--,f*=2),(r+=u+h>=1?l/f:l*Math.pow(2,1-h))*f>=2&&(u++,f/=2),u+h>=s?(a=0,u=s):u+h>=1?(a=(r*f-1)*Math.pow(2,o),u+=h):(a=r*Math.pow(2,h-1)*Math.pow(2,o),u=0));o>=8;t[e+p]=255&a,p+=v,a/=256,o-=8);for(u=u<0;t[e+p]=255&u,p+=v,u/=256,c-=8);t[e+p-v]|=128*g}var jo={}.toString,Ao=Array.isArray||function(t){return"[object Array]"==jo.call(t)};function Eo(){return Po.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function Oo(t,r){if(Eo()=Eo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+Eo().toString(16)+" bytes");return 0|t}function ko(t){return!(null==t||!t._isBuffer)}function Io(t,r){if(ko(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var e=t.length;if(0===e)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return ui(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return ai(t).length;default:if(n)return ui(t).length;r=(""+r).toLowerCase(),n=!0}}function xo(t,r,e){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(r>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return Ho(this,r,e);case"utf8":case"utf-8":return qo(this,r,e);case"ascii":return Wo(this,r,e);case"latin1":case"binary":return Go(this,r,e);case"base64":return $o(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Zo(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function Co(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function Yo(t,r,e,n,o){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=o?0:t.length-1),e<0&&(e=t.length+e),e>=t.length){if(o)return-1;e=t.length-1}else if(e<0){if(!o)return-1;e=0}if("string"==typeof r&&(r=Po.from(r,n)),ko(r))return 0===r.length?-1:Mo(t,r,e,n,o);if("number"==typeof r)return r&=255,Po.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):Mo(t,[r],e,n,o);throw new TypeError("val must be string, number or Buffer")}function Mo(t,r,e,n,o){var i,u=1,a=t.length,f=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||r.length<2)return-1;u=2,a/=2,f/=2,e/=2}function c(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(o){var s=-1;for(i=e;ia&&(e=a-f),i=e;i>=0;i--){for(var h=!0,l=0;lo&&(n=o):n=o;var i=r.length;if(i%2!=0)throw new TypeError("Invalid hex string");n>i/2&&(n=i/2);for(var u=0;u>8,o=e%256,i.push(o),i.push(n);return i}(r,t.length-e),t,e,n)}function $o(t,r,e){return 0===r&&e===t.length?wo(t):wo(t.slice(r,e))}function qo(t,r,e){e=Math.min(t.length,e);for(var n=[],o=r;o239?4:c>223?3:c>191?2:1;if(o+h<=e)switch(h){case 1:c<128&&(s=c);break;case 2:128==(192&(i=t[o+1]))&&(f=(31&c)<<6|63&i)>127&&(s=f);break;case 3:i=t[o+1],u=t[o+2],128==(192&i)&&128==(192&u)&&(f=(15&c)<<12|(63&i)<<6|63&u)>2047&&(f<55296||f>57343)&&(s=f);break;case 4:i=t[o+1],u=t[o+2],a=t[o+3],128==(192&i)&&128==(192&u)&&128==(192&a)&&(f=(15&c)<<18|(63&i)<<12|(63&u)<<6|63&a)>65535&&f<1114112&&(s=f)}null===s?(s=65533,h=1):s>65535&&(s-=65536,n.push(s>>>10&1023|55296),s=56320|1023&s),n.push(s),o+=h}return function(t){var r=t.length;if(r<=Jo)return String.fromCharCode.apply(String,t);var e="",n=0;for(;n0&&(t=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(t+=" ... ")),""},Po.prototype.compare=function(t,r,e,n,o){if(!ko(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===e&&(e=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),r<0||e>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&r>=e)return 0;if(n>=o)return-1;if(r>=e)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(n>>>=0),u=(e>>>=0)-(r>>>=0),a=Math.min(i,u),f=this.slice(n,o),c=t.slice(r,e),s=0;so)&&(e=o),t.length>0&&(e<0||r<0)||r>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return Do(this,t,r,e);case"utf8":case"utf-8":return Lo(this,t,r,e);case"ascii":return zo(this,t,r,e);case"latin1":case"binary":return No(this,t,r,e);case"base64":return Fo(this,t,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Vo(this,t,r,e);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},Po.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Jo=4096;function Wo(t,r,e){var n="";e=Math.min(t.length,e);for(var o=r;on)&&(e=n);for(var o="",i=r;ie)throw new RangeError("Trying to access beyond buffer length")}function Qo(t,r,e,n,o,i){if(!ko(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>o||rt.length)throw new RangeError("Index out of range")}function Xo(t,r,e,n){r<0&&(r=65535+r+1);for(var o=0,i=Math.min(t.length-e,2);o>>8*(n?o:1-o)}function ti(t,r,e,n){r<0&&(r=4294967295+r+1);for(var o=0,i=Math.min(t.length-e,4);o>>8*(n?o:3-o)&255}function ri(t,r,e,n,o,i){if(e+n>t.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function ei(t,r,e,n,o){return o||ri(t,0,e,4),mo(t,r,e,n,23,4),e+4}function ni(t,r,e,n,o){return o||ri(t,0,e,8),mo(t,r,e,n,52,8),e+8}Po.prototype.slice=function(t,r){var e,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(r=void 0===r?n:~~r)<0?(r+=n)<0&&(r=0):r>n&&(r=n),r0&&(o*=256);)n+=this[t+--r]*o;return n},Po.prototype.readUInt8=function(t,r){return r||Ko(t,1,this.length),this[t]},Po.prototype.readUInt16LE=function(t,r){return r||Ko(t,2,this.length),this[t]|this[t+1]<<8},Po.prototype.readUInt16BE=function(t,r){return r||Ko(t,2,this.length),this[t]<<8|this[t+1]},Po.prototype.readUInt32LE=function(t,r){return r||Ko(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},Po.prototype.readUInt32BE=function(t,r){return r||Ko(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},Po.prototype.readIntLE=function(t,r,e){t|=0,r|=0,e||Ko(t,r,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*r)),n},Po.prototype.readIntBE=function(t,r,e){t|=0,r|=0,e||Ko(t,r,this.length);for(var n=r,o=1,i=this[t+--n];n>0&&(o*=256);)i+=this[t+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*r)),i},Po.prototype.readInt8=function(t,r){return r||Ko(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},Po.prototype.readInt16LE=function(t,r){r||Ko(t,2,this.length);var e=this[t]|this[t+1]<<8;return 32768&e?4294901760|e:e},Po.prototype.readInt16BE=function(t,r){r||Ko(t,2,this.length);var e=this[t+1]|this[t]<<8;return 32768&e?4294901760|e:e},Po.prototype.readInt32LE=function(t,r){return r||Ko(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},Po.prototype.readInt32BE=function(t,r){return r||Ko(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},Po.prototype.readFloatLE=function(t,r){return r||Ko(t,4,this.length),_o(this,t,!0,23,4)},Po.prototype.readFloatBE=function(t,r){return r||Ko(t,4,this.length),_o(this,t,!1,23,4)},Po.prototype.readDoubleLE=function(t,r){return r||Ko(t,8,this.length),_o(this,t,!0,52,8)},Po.prototype.readDoubleBE=function(t,r){return r||Ko(t,8,this.length),_o(this,t,!1,52,8)},Po.prototype.writeUIntLE=function(t,r,e,n){(t=+t,r|=0,e|=0,n)||Qo(this,t,r,e,Math.pow(2,8*e)-1,0);var o=1,i=0;for(this[r]=255&t;++i=0&&(i*=256);)this[r+o]=t/i&255;return r+e},Po.prototype.writeUInt8=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,1,255,0),Po.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[r]=255&t,r+1},Po.prototype.writeUInt16LE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,2,65535,0),Po.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Xo(this,t,r,!0),r+2},Po.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,2,65535,0),Po.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Xo(this,t,r,!1),r+2},Po.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,4,4294967295,0),Po.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):ti(this,t,r,!0),r+4},Po.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,4,4294967295,0),Po.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):ti(this,t,r,!1),r+4},Po.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Qo(this,t,r,e,o-1,-o)}var i=0,u=1,a=0;for(this[r]=255&t;++i>0)-a&255;return r+e},Po.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Qo(this,t,r,e,o-1,-o)}var i=e-1,u=1,a=0;for(this[r+i]=255&t;--i>=0&&(u*=256);)t<0&&0===a&&0!==this[r+i+1]&&(a=1),this[r+i]=(t/u>>0)-a&255;return r+e},Po.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,1,127,-128),Po.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},Po.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,2,32767,-32768),Po.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Xo(this,t,r,!0),r+2},Po.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,2,32767,-32768),Po.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Xo(this,t,r,!1),r+2},Po.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,4,2147483647,-2147483648),Po.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):ti(this,t,r,!0),r+4},Po.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||Qo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),Po.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):ti(this,t,r,!1),r+4},Po.prototype.writeFloatLE=function(t,r,e){return ei(this,t,r,!0,e)},Po.prototype.writeFloatBE=function(t,r,e){return ei(this,t,r,!1,e)},Po.prototype.writeDoubleLE=function(t,r,e){return ni(this,t,r,!0,e)},Po.prototype.writeDoubleBE=function(t,r,e){return ni(this,t,r,!1,e)},Po.prototype.copy=function(t,r,e,n){if(e||(e=0),n||0===n||(n=this.length),r>=t.length&&(r=t.length),r||(r=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-r=0;--o)t[o+r]=this[o+e];else if(i<1e3||!Po.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,e=void 0===e?this.length:e>>>0,t||(t=0),"number"==typeof t)for(i=r;i55295&&e<57344){if(!o){if(e>56319){(r-=3)>-1&&i.push(239,191,189);continue}if(u+1===n){(r-=3)>-1&&i.push(239,191,189);continue}o=e;continue}if(e<56320){(r-=3)>-1&&i.push(239,191,189),o=e;continue}e=65536+(o-55296<<10|e-56320)}else o&&(r-=3)>-1&&i.push(239,191,189);if(o=null,e<128){if((r-=1)<0)break;i.push(e)}else if(e<2048){if((r-=2)<0)break;i.push(e>>6|192,63&e|128)}else if(e<65536){if((r-=3)<0)break;i.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;i.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return i}function ai(t){return function(t){var r,e,n,o,i,u;go||yo();var a=t.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");i="="===t[a-2]?2:"="===t[a-1]?1:0,u=new vo(3*a/4-i),n=i>0?a-4:a;var f=0;for(r=0,e=0;r>16&255,u[f++]=o>>8&255,u[f++]=255&o;return 2===i?(o=po[t.charCodeAt(r)]<<2|po[t.charCodeAt(r+1)]>>4,u[f++]=255&o):1===i&&(o=po[t.charCodeAt(r)]<<10|po[t.charCodeAt(r+1)]<<4|po[t.charCodeAt(r+2)]>>2,u[f++]=o>>8&255,u[f++]=255&o),u}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(oi,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function fi(t,r,e,n){for(var o=0;o=r.length||o>=t.length);++o)r[o+e]=t[o];return o}function ci(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}c.setTimeout,c.clearTimeout;var si=c.performance||{},hi=(si.now||si.mozNow||si.msNow||si.oNow||si.webkitNow,function(t){return!Bn(t)});function li(t,r){var e=Tn(r,function(t,r){return!t[Wn]});return Ge(e,{})?t:function(t,r){var e={};return r=an(r),sn(t,function(t,n,o){gt(e,r(t,n,o),t)}),e}(t,function(t,r){return function(t,r,e){var n;return e(t,function(t,e,o){if(r(t,e,o))return n=e,!1}),n}(e,an(function(t){return t.alias===r}),sn)||r})}function pi(t,r){return jn(r,function(r,e){var n,o;return mn(t[e])||!0===r[Vn]&&hi(t[e])?En({},r,((n={})[Gn]=!0,n)):((o={})[qn]=t[e],o[Fn]=r[Fn],o[Vn]=r[Vn]||!1,o[$n]=r[$n]||!1,o[Jn]=r[Jn]||!1,o)})}function vi(t,r){var e=function(t,r){var e=li(t,r);return{pristineValues:jn(Tn(r,function(t,r){return so(e,r)}),function(t){return t.args}),checkAgainstAppProps:Tn(r,function(t,r){return!so(e,r)}),config:e}}(t,r),n=e.config,o=e.pristineValues;return[pi(n,e.checkAgainstAppProps),o]}var gi=function(t){return Zn(t)?t:[t]};var yi=function(t,r){return!Zn(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},di=function(t,r){try{return!!D(r)&&r.apply(null,[t])}catch(t){return!1}};function bi(t){return function(r,e){if(r[Gn])return r[qn];var n=function(t,r){var e,n=[[t[qn]],[(e={},e[Fn]=gi(t[Fn]),e[Vn]=t[Vn],e)]];return Reflect.apply(r,null,n)}(r,t);if(n.length)throw ao("runValidationAction",e,r),new oo(e,n);if(!1!==r[$n]&&!yi(r[qn],r[$n]))throw ao($n,r[$n]),new no(e);if(!1!==r[Jn]&&!di(r[qn],r[Jn]))throw ao(Jn,r[Jn]),new io(e);return r[qn]}}function wi(t,r,e,n){return void 0===t&&(t={}),En(function(t,r){var e=t[0],n=t[1],o=jn(e,bi(r));return En(o,n)}(vi(t,r),n),e)}function _i(t,r,e,n,o,i){void 0===e&&(e=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===i&&(i=!1);var u={};return u[Ln]=t,u[Yn]=r,!0===e&&(u[Mn]=!0),Zn(n)&&(u[Dn]=n),D(o)&&(u[zn]=o),dn(i)&&(u[Nn]=i),u}var mi,ji,Ai,Ei,Oi,Pi,Ri,Ti,Si,Ui=Xn,Bi=In,ki=function(t,r,e){void 0===e&&(e={});var n=e[Mn],o=e[Dn],i=e[zn],u=e[Nn];return _i.apply(null,[t,r,n,o,i,u])},Ii=function(t){return function(r,e,n){return void 0===n&&(n={}),wi(r,e,n,t)}}(function(t,r,e){var n;void 0===e&&(e=!1);var o=function(t,r){if(!Zn(r))throw new uo("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!Zn(t))throw new uo("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==r.length:return ao(1),t.map(function(t,e){return{arg:t,index:e,param:r[e]}});case!0===r[0].variable:ao(2);var e=r[0].type;return t.map(function(t,n){return{arg:t,index:n,param:r[n]||{type:e,name:"_"}}});case t.lengthr.length:ao(4);var n=r.length,o=["any"];return t.map(function(t,e){var i=e>=n||!!r[e].optional,u=r[e]||{type:o,name:"_"+e};return{arg:i?co(t,u):t,index:e,param:u,optional:i}});default:throw ao(5),new uo("Could not understand your arguments and parameter structure!",{args:t,params:r})}}(t,r),i=o.filter(function(t){return!0===t.optional||!0===t.param.optional?function(t){var r=t.arg,e=t.param;return!!Bn(r)&&!(e.type.length>e.type.filter(function(r){return fo(r,t)}).length)}(t):!(t.param.type.length>t.param.type.filter(function(r){return fo(r,t)}).length)});return e?((n={}).error=i,n.data=o.map(function(t){return t.arg}),n):i});var xi={algorithm:ki("HS256",["string"]),expiresIn:ki(!1,["boolean","number","string"],(mi={},mi[Nn]="exp",mi[Mn]=!0,mi)),notBefore:ki(!1,["boolean","number","string"],(ji={},ji[Nn]="nbf",ji[Mn]=!0,ji)),audience:ki(!1,["boolean","string"],(Ai={},Ai[Nn]="iss",Ai[Mn]=!0,Ai)),subject:ki(!1,["boolean","string"],(Ei={},Ei[Nn]="sub",Ei[Mn]=!0,Ei)),issuer:ki(!1,["boolean","string"],(Oi={},Oi[Nn]="iss",Oi[Mn]=!0,Oi)),noTimestamp:ki(!1,["boolean"],(Pi={},Pi[Mn]=!0,Pi)),header:ki(!1,["boolean","string"],(Ri={},Ri[Mn]=!0,Ri)),keyid:ki(!1,["boolean","string"],(Ti={},Ti[Mn]=!0,Ti)),mutatePayload:ki(!1,["boolean"],(Si={},Si[Mn]=!0,Si))};t.decodeToken=function(t){if(Bi(t))return function(t){var r=t.iat||ho();if(t.exp&&r>=t.exp){var e=new Date(t.exp).toISOString();throw new uo("Token has expired on "+e,t)}return t}(a(t));throw new uo("Token must be a string!")},t.tokenValidator=function(t){if(!Ui(t))return{};var r={},e=Ii(t,xi);for(var n in e)e[n]&&(r[n]=e[n]);return r},Object.defineProperty(t,"__esModule",{value:!0})}); +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlJwt={})}(this,(function(t){"use strict";var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function n(t){this.message=t}n.prototype=new Error,n.prototype.name="InvalidCharacterError";var e="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new n("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,u,a=0,i=0,c="";u=e.charAt(i++);~u&&(o=a%4?64*o+u:u,a++%4)?c+=String.fromCharCode(255&o>>(-2*a&6)):0)u=r.indexOf(u);return c};var o=function(t){var r=t.replace(/-/g,"+").replace(/_/g,"/");switch(r.length%4){case 0:break;case 2:r+="==";break;case 3:r+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(e(t).replace(/(.)/g,(function(t,r){var n=r.charCodeAt(0).toString(16).toUpperCase();return n.length<2&&(n="0"+n),"%"+n})))}(r)}catch(t){return e(r)}};function u(t){this.message=t}u.prototype=new Error,u.prototype.name="InvalidTokenError";var a=function(t,r){if("string"!=typeof t)throw new u("Invalid token specified");var n=!0===(r=r||{}).header?0:1;try{return JSON.parse(o(t.split(".")[n]))}catch(t){throw new u("Invalid token specified: "+t.message)}},i=u;a.InvalidTokenError=i;var c="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},f="object"==typeof c&&c&&c.Object===Object&&c,l="object"==typeof self&&self&&self.Object===Object&&self,s=f||l||Function("return this")(),p=s.Symbol;function v(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n=e?t:function(t,r,n){var e=-1,o=t.length;r<0&&(r=-r>o?0:o+r),(n=n>o?o:n)<0&&(n+=o),o=r>n?0:n-r>>>0,r>>>=0;for(var u=Array(o);++e-1;);return n}(e,o),function(t,r){for(var n=t.length;n--&&I(r,t[n],0)>-1;);return n}(e,o)+1).join("")}function Y(t){return void 0===t}var K="[object Boolean]";var Q="[object Number]";function X(t){return function(t){return"number"==typeof t||A(t)&&O(t)==Q}(t)&&t!=+t}var Z="[object String]";function tt(t){return"string"==typeof t||!h(t)&&A(t)&&O(t)==Z}function rt(t,r){return function(n){return t(r(n))}}var nt=rt(Object.getPrototypeOf,Object),et="[object Object]",ot=Function.prototype,ut=Object.prototype,at=ot.toString,it=ut.hasOwnProperty,ct=at.call(Object);function ft(t){if(!A(t)||O(t)!=et)return!1;var r=nt(t);if(null===r)return!0;var n=it.call(r,"constructor")&&r.constructor;return"function"==typeof n&&n instanceof n&&at.call(n)==ct}var lt,st=function(t,r,n){for(var e=-1,o=Object(t),u=n(t),a=u.length;a--;){var i=u[lt?a:++e];if(!1===r(o[i],i,o))break}return t};var pt="[object Arguments]";function vt(t){return A(t)&&O(t)==pt}var ht=Object.prototype,dt=ht.hasOwnProperty,yt=ht.propertyIsEnumerable,bt=vt(function(){return arguments}())?vt:function(t){return A(t)&&dt.call(t,"callee")&&!yt.call(t,"callee")};var gt="object"==typeof t&&t&&!t.nodeType&&t,_t=gt&&"object"==typeof module&&module&&!module.nodeType&&module,jt=_t&&_t.exports===gt?s.Buffer:void 0,wt=(jt?jt.isBuffer:void 0)||function(){return!1},mt=9007199254740991,Ot=/^(?:0|[1-9]\d*)$/;function At(t,r){var n=typeof t;return!!(r=null==r?mt:r)&&("number"==n||"symbol"!=n&&Ot.test(t))&&t>-1&&t%1==0&&t-1&&t%1==0&&t<=kt}var Et={};Et["[object Float32Array]"]=Et["[object Float64Array]"]=Et["[object Int8Array]"]=Et["[object Int16Array]"]=Et["[object Int32Array]"]=Et["[object Uint8Array]"]=Et["[object Uint8ClampedArray]"]=Et["[object Uint16Array]"]=Et["[object Uint32Array]"]=!0,Et["[object Arguments]"]=Et["[object Array]"]=Et["[object ArrayBuffer]"]=Et["[object Boolean]"]=Et["[object DataView]"]=Et["[object Date]"]=Et["[object Error]"]=Et["[object Function]"]=Et["[object Map]"]=Et["[object Number]"]=Et["[object Object]"]=Et["[object RegExp]"]=Et["[object Set]"]=Et["[object String]"]=Et["[object WeakMap]"]=!1;var xt,Pt="object"==typeof t&&t&&!t.nodeType&&t,Tt=Pt&&"object"==typeof module&&module&&!module.nodeType&&module,zt=Tt&&Tt.exports===Pt&&f.process,Ct=function(){try{var t=Tt&&Tt.require&&Tt.require("util").types;return t||zt&&zt.binding&&zt.binding("util")}catch(t){}}(),It=Ct&&Ct.isTypedArray,Mt=It?(xt=It,function(t){return xt(t)}):function(t){return A(t)&&St(t.length)&&!!Et[O(t)]},Dt=Object.prototype.hasOwnProperty;function Ft(t,r){var n=h(t),e=!n&&bt(t),o=!n&&!e&&wt(t),u=!n&&!e&&!o&&Mt(t),a=n||e||o||u,i=a?function(t,r){for(var n=-1,e=Array(t);++n-1},Zt.prototype.set=function(t,r){var n=this.__data__,e=Qt(n,t);return e<0?(++this.size,n.push([t,r])):n[e][1]=r,this};var tr,rr=s["__core-js_shared__"],nr=(tr=/[^.]+$/.exec(rr&&rr.keys&&rr.keys.IE_PROTO||""))?"Symbol(src)_1."+tr:"";var er=Function.prototype.toString;function or(t){if(null!=t){try{return er.call(t)}catch(t){}try{return t+""}catch(t){}}return""}var ur=/^\[object .+?Constructor\]$/,ar=Function.prototype,ir=Object.prototype,cr=ar.toString,fr=ir.hasOwnProperty,lr=RegExp("^"+cr.call(fr).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function sr(t){return!(!Ut(t)||function(t){return!!nr&&nr in t}(t))&&(Wt(t)?lr:ur).test(or(t))}function pr(t,r){var n=function(t,r){return null==t?void 0:t[r]}(t,r);return sr(n)?n:void 0}var vr=pr(s,"Map"),hr=pr(Object,"create");var dr="__lodash_hash_undefined__",yr=Object.prototype.hasOwnProperty;var br=Object.prototype.hasOwnProperty;var gr="__lodash_hash_undefined__";function _r(t){var r=-1,n=null==t?0:t.length;for(this.clear();++ri))return!1;var f=u.get(t);if(f&&u.get(r))return f==r;var l=-1,s=!0,p=n&xr?new kr:void 0;for(u.set(t,r),u.set(r,t);++l0){if(++r>=ye)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(de);function je(t,r){return _e(function(t,r,n){return r=he(void 0===r?t.length-1:r,0),function(){for(var e=arguments,o=-1,u=he(e.length-r,0),a=Array(u);++o1?r[e-1]:void 0,u=e>2?r[2]:void 0;for(o=we.length>3&&"function"==typeof o?(e--,o):void 0,u&&function(t,r,n){if(!Ut(n))return!1;var e=typeof r;return!!("number"==e?Gt(n)&&At(r,n.length):"string"==e&&r in n)&&Kt(n[r],t)}(r[0],r[1],u)&&(o=e<3?void 0:o,e=1),t=Object(t);++n0))},Ye=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},Ke=function(t,r){var n=t.arg;return r.length>1?!n.filter((function(t){return!(r.length>r.filter((function(r){return!Ge(r)(t)})).length)})).length:r.length>r.filter((function(t){return!He(n,t)})).length},Qe=function(t,r){if(void 0===r&&(r=null),ft(t)){if(!r)return!0;if(He(r))return!r.filter((function(r){var n=t[r.name];return!(r.type.length>r.type.filter((function(t){var r;return!!Y(n)||(!1!==(r=Ye(t))?!Ke({arg:n},r):!Ge(t)(n))})).length)})).length}return!1},Xe=function(){try{if(window||document)return!0}catch(t){}return!1},Ze=function(){try{if(!Xe()&&c)return!0}catch(t){}return!1};var to=function(t){function r(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];t.apply(this,r)}return t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r,r.where=function(){return Xe()?"browser":Ze()?"node":"unknown"},r}(Error),ro=function(t){function r(){for(var n=[],e=arguments.length;e--;)n[e]=arguments[e];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var n={name:{configurable:!0}};return n.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(r,n),r}(Error),no=function(t){function r(){for(var n=[],e=arguments.length;e--;)n[e]=arguments[e];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var n={name:{configurable:!0}};return n.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(r,n),r}(Error),eo=function(t){function r(){for(var n=[],e=arguments.length;e--;)n[e]=arguments[e];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var n={name:{configurable:!0}};return n.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(r,n),r}(Error),oo=function(t){function r(){for(var n=[],e=arguments.length;e--;)n[e]=arguments[e];t.apply(this,n),this.message=n[0],this.detail=n[1],this.className=r.name,Error.captureStackTrace&&Error.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var n={name:{configurable:!0},statusCode:{configurable:!0}};return n.name.get=function(){return"JsonqlError"},n.statusCode.get=function(){return-1},Object.defineProperties(r,n),r}(to);function uo(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.console&&Reflect.apply(console.log,console,t)}catch(t){}}var ao=function(t,r){var n,e,o,u,a;switch(!0){case"object"===t:return o=(e=r).arg,u=e.param,a=[o],Array.isArray(u.keys)&&u.keys.length&&a.push(u.keys),!Qe.apply(null,a);case"array"===t:return!He(r.arg);case!1!==(n=Ye(t)):return!Ke(r,n);default:return!Ge(t)(r.arg)}},io=function(t,r){return Y(t)?!0!==r.optional||Y(r.defaultvalue)?null:r.defaultvalue:t},co=function(t,r){var n,e=Object.keys(t);return n=r,!!e.filter((function(t){return t===n})).length},fo=function(t){return!Pe(t)};function lo(t,r){var n=xe(r,(function(t,r){return!t[Le]}));return wn(n,{})?t:function(t,r){var n={};return r=Gn(r),Yt(t,(function(t,e,o){Yn(n,r(t,e,o),t)})),n}(t,(function(t,r){return function(t,r,n){var e;return n(t,(function(t,n,o){if(r(t,n,o))return e=n,!1})),e}(n,Gn((function(t){return t.alias===r})),Yt)||r}))}function so(t,r){return Oe(r,(function(r,n){var e,o;return Y(t[n])||!0===r[Ue]&&fo(t[n])?me({},r,((e={})[We]=!0,e)):((o={})[qe]=t[n],o[Re]=r[Re],o[Ue]=r[Ue]||!1,o[Ve]=r[Ve]||!1,o[Je]=r[Je]||!1,o)}))}function po(t,r){var n=function(t,r){var n=lo(t,r);return{pristineValues:Oe(xe(r,(function(t,r){return co(n,r)})),(function(t){return t.args})),checkAgainstAppProps:xe(r,(function(t,r){return!co(n,r)})),config:n}}(t,r),e=n.config,o=n.pristineValues;return[so(e,n.checkAgainstAppProps),o]}var vo=function(t){return He(t)?t:[t]};var ho=function(t,r){return!He(r)||function(t,r){return!!t.filter((function(t){return t===r})).length}(r,t)},yo=function(t,r){try{return!!Wt(r)&&r.apply(null,[t])}catch(t){return!1}};function bo(t){return function(r,n){if(r[We])return r[qe];var e=function(t,r){var n,e=[[t[qe]],[(n={},n[Re]=vo(t[Re]),n[Ue]=t[Ue],n)]];return Reflect.apply(r,null,e)}(r,t);if(e.length)throw uo("runValidationAction",n,r),new no(n,e);if(!1!==r[Ve]&&!ho(r[qe],r[Ve]))throw uo(Ve,r[Ve]),new ro(n);if(!1!==r[Je]&&!yo(r[qe],r[Je]))throw uo(Je,r[Je]),new eo(n);return r[qe]}}function go(t,r,n,e){return void 0===t&&(t={}),me(function(t,r){var n=t[0],e=t[1],o=Oe(n,bo(r));return me(o,e)}(po(t,r),e),n)}function _o(t,r,n,e,o,u){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===u&&(u=!1);var a={};return a[$e]=t,a[Me]=r,!0===n&&(a[De]=!0),He(e)&&(a[Fe]=e),Wt(o)&&(a[Be]=o),tt(u)&&(a[Ne]=u),a}var jo,wo,mo,Oo,Ao,ko,So,Eo,xo,Po=Qe,To=ze,zo=function(t,r,n){void 0===n&&(n={});var e=n[De],o=n[Fe],u=n[Be],a=n[Ne];return _o.apply(null,[t,r,e,o,u,a])},Co=function(t){return function(r,n,e){return void 0===e&&(e={}),go(r,n,e,t)}}((function(t,r,n){var e;void 0===n&&(n=!1);var o=function(t,r){if(!He(r))throw new oo("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!He(t))throw new oo("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==r.length:return uo(1),t.map((function(t,n){return{arg:t,index:n,param:r[n]}}));case!0===r[0].variable:uo(2);var n=r[0].type;return t.map((function(t,e){return{arg:t,index:e,param:r[e]||{type:n,name:"_"}}}));case t.lengthr.length:uo(4);var e=r.length,o=["any"];return t.map((function(t,n){var u=n>=e||!!r[n].optional,a=r[n]||{type:o,name:"_"+n};return{arg:u?io(t,a):t,index:n,param:a,optional:u}}));default:throw uo(5),new oo("Could not understand your arguments and parameter structure!",{args:t,params:r})}}(t,r),u=o.filter((function(t){return!0===t.optional||!0===t.param.optional?function(t){var r=t.arg,n=t.param;return!!Pe(r)&&!(n.type.length>n.type.filter((function(r){return ao(r,t)})).length)}(t):!(t.param.type.length>t.param.type.filter((function(r){return ao(r,t)})).length)}));return n?((e={}).error=u,e.data=o.map((function(t){return t.arg})),e):u})),Io=function(t){void 0===t&&(t=!1);var r=Date.now();return t?Math.floor(r/1e3):r};var Mo={algorithm:zo("HS256",["string"]),expiresIn:zo(!1,["boolean","number","string"],(jo={},jo[Ne]="exp",jo[De]=!0,jo)),notBefore:zo(!1,["boolean","number","string"],(wo={},wo[Ne]="nbf",wo[De]=!0,wo)),audience:zo(!1,["boolean","string"],(mo={},mo[Ne]="iss",mo[De]=!0,mo)),subject:zo(!1,["boolean","string"],(Oo={},Oo[Ne]="sub",Oo[De]=!0,Oo)),issuer:zo(!1,["boolean","string"],(Ao={},Ao[Ne]="iss",Ao[De]=!0,Ao)),noTimestamp:zo(!1,["boolean"],(ko={},ko[De]=!0,ko)),header:zo(!1,["boolean","string"],(So={},So[De]=!0,So)),keyid:zo(!1,["boolean","string"],(Eo={},Eo[De]=!0,Eo)),mutatePayload:zo(!1,["boolean"],(xo={},xo[De]=!0,xo))};t.decodeToken=function(t){if(To(t))return function(t){var r=t.iat||Io(!0);if(t.exp&&r>=t.exp){var n=new Date(t.exp).toISOString();throw new oo("Token has expired on "+n,t)}return t}(a(t));throw new oo("Token must be a string!")},t.tokenValidator=function(t){if(!Po(t))return{};var r={},n=Co(t,Mo);for(var e in n)n[e]&&(r[e]=n[e]);return r},Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=jsonql-jwt.js.map diff --git a/packages/jwt/package.json b/packages/jwt/package.json index a5f69cae2da50ac8974a177b7209ee6e239ad5b1..19419375797400dd6ae0d801755b36b3a57c593c 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,13 +1,13 @@ { "name": "jsonql-jwt", - "version": "1.3.1", + "version": "1.3.2", "description": "jwt authentication helpers library for jsonql browser / node", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-jwt.js", "scripts": { "test": "npm run build && npm run test:run", - "test:run": "DEBUG=jsonql-jwt* ava", + "test:run": "DEBUG=jsonql-jwt* ava --verbose", "build": "npm run build:decode && npm run build:main", "build:main": "rollup -c", "build:decode": "rollup -c ./rollup.decode-jwt.config.js", @@ -38,10 +38,10 @@ "dependencies": { "colors": "^1.3.3", "fs-extra": "^8.1.0", - "jsonql-constants": "^1.8.2", - "jsonql-errors": "^1.1.2", - "jsonql-params-validator": "^1.4.8", - "jsonql-utils": "^0.4.6", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.6.10", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", @@ -53,11 +53,11 @@ "devDependencies": { "socket.io-client": "^2.2.0", "ws": "^7.1.2", - "ava": "^2.3.0", + "ava": "^2.4.0", "debug": "^4.1.1", "esm": "^3.2.25", "koa": "^2.8.1", - "rollup": "^1.20.3", + "rollup": "^1.21.4", "rollup-plugin-alias": "^2.0.0", "rollup-plugin-async": "^1.2.0", "rollup-plugin-buble": "^0.19.8", @@ -70,7 +70,7 @@ "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^5.1.1", + "rollup-plugin-terser": "^5.1.2", "server-io-core": "^1.2.0", "socket.io": "^2.2.0" }, diff --git a/packages/jwt/rollup.config.js b/packages/jwt/rollup.config.js index 3400f01acb35f40adaf0a7ed6d5594f5167a54e1..863f1d1af3770a5c1a0c7355bf4a7b26f93dca8f 100644 --- a/packages/jwt/rollup.config.js +++ b/packages/jwt/rollup.config.js @@ -40,9 +40,9 @@ let plugins = [ '__PLACEHOLDER__': `version: ${version} module: UMD` }) ] - +plugins.push(terser()) if (env === 'production') { - plugins.push(terser()) + } plugins.push(size()) @@ -52,7 +52,7 @@ let config = { name: 'jsonqlJwt', file: join(__dirname, 'dist', 'jsonql-jwt.js'), format: 'umd', - sourceMap: true, + sourcemap: true, globals: { 'socket.io-client': 'io', 'promise-polyfill': 'Promise', diff --git a/packages/jwt/rollup.decode-jwt.config.js b/packages/jwt/rollup.decode-jwt.config.js index e7921eec2e3bd7a0eef8144e3ca13e265d521010..5059eb8a9f0c24d7360370d1e6edcbe1c8aad1d5 100644 --- a/packages/jwt/rollup.decode-jwt.config.js +++ b/packages/jwt/rollup.decode-jwt.config.js @@ -43,7 +43,7 @@ let plugins = [ ]; let config = { - input: join(__dirname, 'src', 'client', 'decode-token', 'index.js'), + input: join(__dirname, 'src', 'client', 'index.js'), output: { name: 'jsonqlJwtHelpers', file: join(__dirname, 'src', 'jwt', 'decode-token.js'), diff --git a/packages/jwt/src/client/decode-token/decode-token.js b/packages/jwt/src/client/decode-token/decode-token.js index 3c92b0bf807f4b3e4a382029a8c7e7da5e6846a2..f322c86c1bbb5304e0e00a107491c09a2e1dc172 100644 --- a/packages/jwt/src/client/decode-token/decode-token.js +++ b/packages/jwt/src/client/decode-token/decode-token.js @@ -5,14 +5,21 @@ import jwt_decode from 'jwt-decode' import { isString } from 'jsonql-params-validator' import { JsonqlError } from 'jsonql-errors' -import { timestamp } from 'jsonql-utils' + +const timestamp = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; +} + /** * We only check the nbf and exp * @param {object} token for checking * @return {object} token on success */ function validate(token) { - const start = token.iat || timestamp() + const start = token.iat || timestamp(true) // we only check the exp for the time being if (token.exp) { if (start >= token.exp) { diff --git a/packages/jwt/src/client/decode-token/index.js b/packages/jwt/src/client/decode-token/index.js deleted file mode 100644 index 607304afed8ee2b1902ec77da764bc845520355c..0000000000000000000000000000000000000000 --- a/packages/jwt/src/client/decode-token/index.js +++ /dev/null @@ -1,9 +0,0 @@ - - -import decodeToken from './decode-token' -import tokenValidator from './token-validator' - -export { - tokenValidator, - decodeToken -} diff --git a/packages/jwt/src/client/index.js b/packages/jwt/src/client/index.js index 75892232e458505acdbe9097ca279d04d104888f..731487ca00f2129fb9d64ffb7a4e7b0cdaa2837a 100644 --- a/packages/jwt/src/client/index.js +++ b/packages/jwt/src/client/index.js @@ -13,12 +13,10 @@ import { moved to @jsonql/ws import { wsAuthClient, wsClient } from './ws/auth-client' */ -import { decodeToken, tokenValidator } from './decode-token' - +import decodeToken from './decode-token/decode-token' +import tokenValidator from './decode-token/token-validator' export { - decodeToken, tokenValidator - } diff --git a/packages/jwt/src/jwt/decode-token.js b/packages/jwt/src/jwt/decode-token.js index cad4359463b0cfa72de461e7e49cabaf23fecfc6..4bba43447eb8013bda613b7dfa06877a9209a5f6 100644 --- a/packages/jwt/src/jwt/decode-token.js +++ b/packages/jwt/src/jwt/decode-token.js @@ -7,2016 +7,23 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var jwt_decode = _interopDefault(require('jwt-decode')); var jsonqlParamsValidator = require('jsonql-params-validator'); var jsonqlErrors = require('jsonql-errors'); -require('debug'); -var OPTIONAL_KEY = 'optional'; -var ALIAS_KEY = 'alias'; - -var STRING_TYPE = 'string'; -var BOOLEAN_TYPE = 'boolean'; - -var NUMBER_TYPE = 'number'; -var HSA_ALGO = 'HS256'; - -var global$1 = (typeof global !== "undefined" ? global : - typeof self !== "undefined" ? self : - typeof window !== "undefined" ? window : {}); - -// bunch of generic helpers - -/** - * @param {boolean} sec return in second or not - * @return {number} timestamp - */ -var timestamp = function (sec) { - if ( sec === void 0 ) sec = false; - - var time = Date.now(); - return sec ? Math.floor( time / 1000 ) : time; -}; - -var lookup = []; -var revLookup = []; -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; -var inited = false; -function init () { - inited = true; - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i]; - revLookup[code.charCodeAt(i)] = i; - } - - revLookup['-'.charCodeAt(0)] = 62; - revLookup['_'.charCodeAt(0)] = 63; -} - -function toByteArray (b64) { - if (!inited) { - init(); - } - var i, j, l, tmp, placeHolders, arr; - var len = b64.length; - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders); - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len; - - var L = 0; - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; - arr[L++] = (tmp >> 16) & 0xFF; - arr[L++] = (tmp >> 8) & 0xFF; - arr[L++] = tmp & 0xFF; - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); - arr[L++] = tmp & 0xFF; - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); - arr[L++] = (tmp >> 8) & 0xFF; - arr[L++] = tmp & 0xFF; - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp; - var output = []; - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); - output.push(tripletToBase64(tmp)); - } - return output.join('') -} - -function fromByteArray (uint8) { - if (!inited) { - init(); - } - var tmp; - var len = uint8.length; - var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes - var output = ''; - var parts = []; - var maxChunkLength = 16383; // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1]; - output += lookup[tmp >> 2]; - output += lookup[(tmp << 4) & 0x3F]; - output += '=='; - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); - output += lookup[tmp >> 10]; - output += lookup[(tmp >> 4) & 0x3F]; - output += lookup[(tmp << 2) & 0x3F]; - output += '='; - } - - parts.push(output); - - return parts.join('') -} - -function read (buffer, offset, isLE, mLen, nBytes) { - var e, m; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var nBits = -7; - var i = isLE ? (nBytes - 1) : 0; - var d = isLE ? -1 : 1; - var s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -function write (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); - var i = isLE ? 0 : (nBytes - 1); - var d = isLE ? 1 : -1; - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128; -} - -var toString = {}.toString; - -var isArray = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - -var INSPECT_MAX_BYTES = 50; - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined - ? global$1.TYPED_ARRAY_SUPPORT - : true; - -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} - -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length); - that.__proto__ = Buffer.prototype; - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length); - } - that.length = length; - } - - return that -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } - - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} - -Buffer.poolSize = 8192; // not used by this implementation - -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype; - return arr -}; - -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } - - return fromObject(that, value) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) -}; - -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype; - Buffer.__proto__ = Uint8Array; -} - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size); - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -}; - -function allocUnsafe (that, size) { - assertSize(size); - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0; - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -}; -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -}; - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8'; - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - var length = byteLength(string, encoding) | 0; - that = createBuffer(that, length); - - var actual = that.write(string, encoding); - - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - that = that.slice(0, actual); - } - - return that -} - -function fromArrayLike (that, array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0; - that = createBuffer(that, length); - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255; - } - return that -} - -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength; // this throws if `array` is not a valid ArrayBuffer - - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } - - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array); - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset); - } else { - array = new Uint8Array(array, byteOffset, length); - } - - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array; - that.__proto__ = Buffer.prototype; - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array); - } - return that -} - -function fromObject (that, obj) { - if (internalIsBuffer(obj)) { - var len = checked(obj.length) | 0; - that = createBuffer(that, len); - - if (that.length === 0) { - return that - } - - obj.copy(that, 0, 0, len); - return that - } - - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } - - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } - - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} - -function checked (length) { - // Note: cannot use `length < kMaxLength()` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} -Buffer.isBuffer = isBuffer; -function internalIsBuffer (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.compare = function compare (a, b) { - if (!internalIsBuffer(a) || !internalIsBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) { return 0 } - - var x = a.length; - var y = b.length; - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i]; - y = b[i]; - break - } - } - - if (x < y) { return -1 } - if (y < x) { return 1 } - return 0 -}; - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -}; - -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i; - if (length === undefined) { - length = 0; - for (i = 0; i < list.length; ++i) { - length += list[i].length; - } - } - - var buffer = Buffer.allocUnsafe(length); - var pos = 0; - for (i = 0; i < list.length; ++i) { - var buf = list[i]; - if (!internalIsBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos); - pos += buf.length; - } - return buffer -}; - -function byteLength (string, encoding) { - if (internalIsBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string; - } - - var len = string.length; - if (len === 0) { return 0 } - - // Use a for loop to avoid recursion - var loweredCase = false; - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) { return utf8ToBytes(string).length } // assume utf8 - encoding = ('' + encoding).toLowerCase(); - loweredCase = true; - } - } -} -Buffer.byteLength = byteLength; - -function slowToString (encoding, start, end) { - var loweredCase = false; - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0; - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length; - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0; - start >>>= 0; - - if (end <= start) { - return '' - } - - if (!encoding) { encoding = 'utf8'; } - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } - encoding = (encoding + '').toLowerCase(); - loweredCase = true; - } - } -} - -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true; - -function swap (b, n, m) { - var i = b[n]; - b[n] = b[m]; - b[m] = i; -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length; - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1); - } - return this -}; - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length; - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3); - swap(this, i + 1, i + 2); - } - return this -}; - -Buffer.prototype.swap64 = function swap64 () { - var len = this.length; - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7); - swap(this, i + 1, i + 6); - swap(this, i + 2, i + 5); - swap(this, i + 3, i + 4); - } - return this -}; - -Buffer.prototype.toString = function toString () { - var length = this.length | 0; - if (length === 0) { return '' } - if (arguments.length === 0) { return utf8Slice(this, 0, length) } - return slowToString.apply(this, arguments) -}; - -Buffer.prototype.equals = function equals (b) { - if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } - if (this === b) { return true } - return Buffer.compare(this, b) === 0 -}; - -Buffer.prototype.inspect = function inspect () { - var str = ''; - var max = INSPECT_MAX_BYTES; - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' '); - if (this.length > max) { str += ' ... '; } - } - return '' -}; - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!internalIsBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0; - } - if (end === undefined) { - end = target ? target.length : 0; - } - if (thisStart === undefined) { - thisStart = 0; - } - if (thisEnd === undefined) { - thisEnd = this.length; - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0; - end >>>= 0; - thisStart >>>= 0; - thisEnd >>>= 0; - - if (this === target) { return 0 } - - var x = thisEnd - thisStart; - var y = end - start; - var len = Math.min(x, y); - - var thisCopy = this.slice(thisStart, thisEnd); - var targetCopy = target.slice(start, end); - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i]; - y = targetCopy[i]; - break - } - } - - if (x < y) { return -1 } - if (y < x) { return 1 } - return 0 -}; - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) { return -1 } - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset; - byteOffset = 0; - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff; - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000; - } - byteOffset = +byteOffset; // Coerce to Number. - if (isNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1); - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) { byteOffset = buffer.length + byteOffset; } - if (byteOffset >= buffer.length) { - if (dir) { return -1 } - else { byteOffset = buffer.length - 1; } - } else if (byteOffset < 0) { - if (dir) { byteOffset = 0; } - else { return -1 } - } - - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding); - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (internalIsBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF; // Search for a byte value [0-255] - if (Buffer.TYPED_ARRAY_SUPPORT && - typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1; - var arrLength = arr.length; - var valLength = val.length; - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase(); - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2; - arrLength /= 2; - valLength /= 2; - byteOffset /= 2; - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i; - if (dir) { - var foundIndex = -1; - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) { foundIndex = i; } - if (i - foundIndex + 1 === valLength) { return foundIndex * indexSize } - } else { - if (foundIndex !== -1) { i -= i - foundIndex; } - foundIndex = -1; - } - } - } else { - if (byteOffset + valLength > arrLength) { byteOffset = arrLength - valLength; } - for (i = byteOffset; i >= 0; i--) { - var found = true; - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false; - break - } - } - if (found) { return i } - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -}; - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -}; - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -}; - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0; - var remaining = buf.length - offset; - if (!length) { - length = remaining; - } else { - length = Number(length); - if (length > remaining) { - length = remaining; - } - } - - // must be an even number of digits - var strLen = string.length; - if (strLen % 2 !== 0) { throw new TypeError('Invalid hex string') } - - if (length > strLen / 2) { - length = strLen / 2; - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16); - if (isNaN(parsed)) { return i } - buf[offset + i] = parsed; - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8'; - length = this.length; - offset = 0; - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset; - length = this.length; - offset = 0; - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0; - if (isFinite(length)) { - length = length | 0; - if (encoding === undefined) { encoding = 'utf8'; } - } else { - encoding = length; - length = undefined; - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset; - if (length === undefined || length > remaining) { length = remaining; } - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) { encoding = 'utf8'; } - - var loweredCase = false; - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } - encoding = ('' + encoding).toLowerCase(); - loweredCase = true; - } - } -}; - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -}; - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return fromByteArray(buf) - } else { - return fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end); - var res = []; - - var i = start; - while (i < end) { - var firstByte = buf[i]; - var codePoint = null; - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1; - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint; - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte; - } - break - case 2: - secondByte = buf[i + 1]; - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint; - } - } - break - case 3: - secondByte = buf[i + 1]; - thirdByte = buf[i + 2]; - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint; - } - } - break - case 4: - secondByte = buf[i + 1]; - thirdByte = buf[i + 2]; - fourthByte = buf[i + 3]; - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint; - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD; - bytesPerSequence = 1; - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000; - res.push(codePoint >>> 10 & 0x3FF | 0xD800); - codePoint = 0xDC00 | codePoint & 0x3FF; - } - - res.push(codePoint); - i += bytesPerSequence; - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000; - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length; - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = ''; - var i = 0; - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ); - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = ''; - end = Math.min(buf.length, end); - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F); - } - return ret -} - -function latin1Slice (buf, start, end) { - var ret = ''; - end = Math.min(buf.length, end); - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]); - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length; - - if (!start || start < 0) { start = 0; } - if (!end || end < 0 || end > len) { end = len; } - - var out = ''; - for (var i = start; i < end; ++i) { - out += toHex(buf[i]); - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end); - var res = ''; - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length; - start = ~~start; - end = end === undefined ? len : ~~end; - - if (start < 0) { - start += len; - if (start < 0) { start = 0; } - } else if (start > len) { - start = len; - } - - if (end < 0) { - end += len; - if (end < 0) { end = 0; } - } else if (end > len) { - end = len; - } - - if (end < start) { end = start; } - - var newBuf; - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end); - newBuf.__proto__ = Buffer.prototype; - } else { - var sliceLen = end - start; - newBuf = new Buffer(sliceLen, undefined); - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start]; - } - } - - return newBuf -}; - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) { throw new RangeError('offset is not uint') } - if (offset + ext > length) { throw new RangeError('Trying to access beyond buffer length') } -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { checkOffset(offset, byteLength, this.length); } - - var val = this[offset]; - var mul = 1; - var i = 0; - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul; - } - - return val -}; - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { - checkOffset(offset, byteLength, this.length); - } - - var val = this[offset + --byteLength]; - var mul = 1; - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul; - } - - return val -}; - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 1, this.length); } - return this[offset] -}; - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return this[offset] | (this[offset + 1] << 8) -}; - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return (this[offset] << 8) | this[offset + 1] -}; - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -}; - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -}; - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { checkOffset(offset, byteLength, this.length); } - - var val = this[offset]; - var mul = 1; - var i = 0; - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul; - } - mul *= 0x80; - - if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } - - return val -}; - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { checkOffset(offset, byteLength, this.length); } - - var i = byteLength; - var mul = 1; - var val = this[offset + --i]; - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul; - } - mul *= 0x80; - - if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } - - return val -}; - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 1, this.length); } - if (!(this[offset] & 0x80)) { return (this[offset]) } - return ((0xff - this[offset] + 1) * -1) -}; - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - var val = this[offset] | (this[offset + 1] << 8); - return (val & 0x8000) ? val | 0xFFFF0000 : val -}; - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - var val = this[offset + 1] | (this[offset] << 8); - return (val & 0x8000) ? val | 0xFFFF0000 : val -}; - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -}; - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -}; - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, true, 23, 4) -}; - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, false, 23, 4) -}; - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 8, this.length); } - return read(this, offset, true, 52, 8) -}; - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 8, this.length); } - return read(this, offset, false, 52, 8) -}; - -function checkInt (buf, value, offset, ext, max, min) { - if (!internalIsBuffer(buf)) { throw new TypeError('"buffer" argument must be a Buffer instance') } - if (value > max || value < min) { throw new RangeError('"value" argument is out of bounds') } - if (offset + ext > buf.length) { throw new RangeError('Index out of range') } -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value; - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1; - checkInt(this, value, offset, byteLength, maxBytes, 0); - } - - var mul = 1; - var i = 0; - this[offset] = value & 0xFF; - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF; - } - - return offset + byteLength -}; - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value; - offset = offset | 0; - byteLength = byteLength | 0; - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1; - checkInt(this, value, offset, byteLength, maxBytes, 0); - } - - var i = byteLength - 1; - var mul = 1; - this[offset + i] = value & 0xFF; - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF; - } - - return offset + byteLength -}; - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } - if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } - this[offset] = (value & 0xff); - return offset + 1 -}; - -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) { value = 0xffff + value + 1; } - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8; - } -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 -}; - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8); - this[offset + 1] = (value & 0xff); - } else { - objectWriteUInt16(this, value, offset, false); - } - return offset + 2 -}; - -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) { value = 0xffffffff + value + 1; } - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff; - } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24); - this[offset + 2] = (value >>> 16); - this[offset + 1] = (value >>> 8); - this[offset] = (value & 0xff); - } else { - objectWriteUInt32(this, value, offset, true); - } - return offset + 4 -}; - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24); - this[offset + 1] = (value >>> 16); - this[offset + 2] = (value >>> 8); - this[offset + 3] = (value & 0xff); - } else { - objectWriteUInt32(this, value, offset, false); - } - return offset + 4 -}; - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1); - - checkInt(this, value, offset, byteLength, limit - 1, -limit); - } - - var i = 0; - var mul = 1; - var sub = 0; - this[offset] = value & 0xFF; - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1; - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; - } - - return offset + byteLength -}; - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1); - - checkInt(this, value, offset, byteLength, limit - 1, -limit); - } - - var i = byteLength - 1; - var mul = 1; - var sub = 0; - this[offset + i] = value & 0xFF; - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1; - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; - } - - return offset + byteLength -}; - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } - if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } - if (value < 0) { value = 0xff + value + 1; } - this[offset] = (value & 0xff); - return offset + 1 -}; - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 -}; - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8); - this[offset + 1] = (value & 0xff); - } else { - objectWriteUInt16(this, value, offset, false); - } - return offset + 2 -}; - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - this[offset + 2] = (value >>> 16); - this[offset + 3] = (value >>> 24); - } else { - objectWriteUInt32(this, value, offset, true); - } - return offset + 4 -}; - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } - if (value < 0) { value = 0xffffffff + value + 1; } - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24); - this[offset + 1] = (value >>> 16); - this[offset + 2] = (value >>> 8); - this[offset + 3] = (value & 0xff); - } else { - objectWriteUInt32(this, value, offset, false); - } - return offset + 4 -}; - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) { throw new RangeError('Index out of range') } - if (offset < 0) { throw new RangeError('Index out of range') } -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4); - } - write(buf, value, offset, littleEndian, 23, 4); - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -}; - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -}; - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8); - } - write(buf, value, offset, littleEndian, 52, 8); - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -}; - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -}; - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) { start = 0; } - if (!end && end !== 0) { end = this.length; } - if (targetStart >= target.length) { targetStart = target.length; } - if (!targetStart) { targetStart = 0; } - if (end > 0 && end < start) { end = start; } - - // Copy 0 bytes; we're done - if (end === start) { return 0 } - if (target.length === 0 || this.length === 0) { return 0 } - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) { throw new RangeError('sourceStart out of bounds') } - if (end < 0) { throw new RangeError('sourceEnd out of bounds') } - - // Are we oob? - if (end > this.length) { end = this.length; } - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start; - } - - var len = end - start; - var i; - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start]; - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start]; - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ); - } - - return len -}; - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start; - start = 0; - end = this.length; - } else if (typeof end === 'string') { - encoding = end; - end = this.length; - } - if (val.length === 1) { - var code = val.charCodeAt(0); - if (code < 256) { - val = code; - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255; - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0; - end = end === undefined ? this.length : end >>> 0; - - if (!val) { val = 0; } +// when the user is login with the jwt - var i; - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val; - } - } else { - var bytes = internalIsBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()); - var len = bytes.length; - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len]; - } - } +var timestamp = function (sec) { + if ( sec === void 0 ) { sec = false; } - return this + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; }; -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g; - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, ''); - // Node converts strings with length < 2 to '' - if (str.length < 2) { return '' } - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '='; - } - return str -} - -function stringtrim (str) { - if (str.trim) { return str.trim() } - return str.replace(/^\s+|\s+$/g, '') -} - -function toHex (n) { - if (n < 16) { return '0' + n.toString(16) } - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity; - var codePoint; - var length = string.length; - var leadSurrogate = null; - var bytes = []; - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i); - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - continue - } - - // valid lead - leadSurrogate = codePoint; - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - leadSurrogate = codePoint; - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - } - - leadSurrogate = null; - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) { break } - bytes.push(codePoint); - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) { break } - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ); - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) { break } - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ); - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) { break } - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ); - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = []; - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF); - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo; - var byteArray = []; - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) { break } - - c = str.charCodeAt(i); - hi = c >> 8; - lo = c % 256; - byteArray.push(lo); - byteArray.push(hi); - } - - return byteArray -} - - -function base64ToBytes (str) { - return toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) { break } - dst[i + offset] = src[i]; - } - return i -} - -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - - -// the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -function isBuffer(obj) { - return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) -} - -function isFastBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) -} - -if (typeof global$1.setTimeout === 'function') ; -if (typeof global$1.clearTimeout === 'function') ; - -// from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js -var performance = global$1.performance || {}; -var performanceNow = - performance.now || - performance.mozNow || - performance.msNow || - performance.oNow || - performance.webkitNow || - function(){ return (new Date()).getTime() }; - -// when the user is login with the jwt /** * We only check the nbf and exp * @param {object} token for checking * @return {object} token on success */ function validate(token) { - var start = token.iat || timestamp(); + var start = token.iat || timestamp(true); // we only check the exp for the time being if (token.exp) { if (start >= token.exp) { @@ -2042,6 +49,15 @@ function jwtDecode(token) { throw new jsonqlErrors.JsonqlError('Token must be a string!') } +var OPTIONAL_KEY = 'optional'; +var ALIAS_KEY = 'alias'; + +var STRING_TYPE = 'string'; +var BOOLEAN_TYPE = 'boolean'; + +var NUMBER_TYPE = 'number'; +var HSA_ALGO = 'HS256'; + var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; var appProps = { diff --git a/packages/koa/package.json b/packages/koa/package.json index b3af783856793753cecbf5614277878a24ac2d3f..565ecbaef5ea68917e5a0f3c1612062227571181 100755 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -23,25 +23,19 @@ "debug": "^4.1.1", "esm": "^3.2.25", "fs-extra": "^8.1.0", - "jsonql-constants": "^1.8.2", + "jsonql-constants": "^1.8.3", "jsonql-contract": "^1.7.8", - "jsonql-errors": "^1.1.2", + "jsonql-errors": "^1.1.3", "jsonql-jwt": "^1.3.1", - "jsonql-node-client": "^1.1.7", + "jsonql-node-client": "^1.1.8", "jsonql-params-validator": "^1.4.8", - "jsonql-resolver": "^0.7.0", - "jsonql-utils": "^0.4.6", + "jsonql-resolver": "^0.8.0", + "jsonql-utils": "^0.4.9", "jsonql-web-console": "^0.4.3", "koa": "^2.8.1", "koa-compose": "^4.1.0", "lodash": "^4.17.15" }, - "author": "to1source ", - "contributors": [ - "NEWBRAN LTD " - ], - "homepage": "jsonql.org", - "license": "MIT", "devDependencies": { "ava": "^2.3.0", "jwt-decode": "^2.2.0", @@ -51,6 +45,12 @@ "server-io-core": "^1.2.0", "superkoa": "^1.0.3" }, + "author": "to1source ", + "contributors": [ + "NEWBRAN LTD " + ], + "homepage": "jsonql.org", + "license": "MIT", "repository": { "type": "git", "url": "git+ssh://git@gitee.com:to1source/jsonql.git" diff --git a/packages/node-client/package.json b/packages/node-client/package.json index 0f93fa51b40fa9d5fcc486f027ffbb34125aa60c..dae5c381c27c21e673e9cb5480aad7ba95ae856d 100755 --- a/packages/node-client/package.json +++ b/packages/node-client/package.json @@ -38,15 +38,15 @@ "jsonql-constants": "^1.8.3", "jsonql-contract": "^1.7.8", "jsonql-errors": "^1.1.3", - "jsonql-jwt": "^1.3.1", - "jsonql-params-validator": "^1.4.8", - "jsonql-utils": "^0.4.9", + "jsonql-jwt": "^1.3.2", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.6.10", "lodash.merge": "^4.6.2", "node-cache": "^4.2.1", "request": "^2.88.0" }, "devDependencies": { - "ava": "^2.3.0", + "ava": "^2.4.0", "jsonql-koa": "^1.3.8", "nyc": "^14.1.1", "server-io-core": "^1.2.0" diff --git a/packages/node-client/src/utils.js b/packages/node-client/src/utils.js index 6cb33b61921f4b2c4f3b328092bdac6ed8a9aff4..1cd71a5899ee96a05e492b1464681788530e4388 100755 --- a/packages/node-client/src/utils.js +++ b/packages/node-client/src/utils.js @@ -1,6 +1,6 @@ const { inspect } = require('util') - -const { isKeyInObject, getDebug, resultHandler } = require('jsonql-utils') +const debug = require('debug') +const { isKeyInObject, resultHandler } = require('jsonql-utils') const MODULE_NAME = 'jsonql-node-client' const display = (data, full = false) => ( @@ -13,6 +13,6 @@ module.exports = { isKeyInObject, resultHandler, getDebug: function(name) { - return getDebug(name, MODULE_NAME) + return debug(MODULE_NAME).extend(name) } } diff --git a/packages/node-client/tests/validation.test.js b/packages/node-client/tests/validation.test.js index 9afa7b004fb69212fe08b35d29fa0ce31772e6d1..1db3d31a8d2e8b2c34de1780047745247c17f089 100644 --- a/packages/node-client/tests/validation.test.js +++ b/packages/node-client/tests/validation.test.js @@ -46,7 +46,7 @@ test('Should failed and throw JsonqlValidationError', async t => { // @TODO the problem is inside the resolver as well as the koa middleware // we need to investigate more where it happens -test.skip("Pass an index larger than the database size to cause it throw application error", async t => { +test.only("Pass an index larger than the database size to cause it throw application error", async t => { const c = t.context.client; const e = await t.throwsAsync( async () => { return await c.query.getUser(100) diff --git a/packages/post/README.md b/packages/postinstall/README.md similarity index 100% rename from packages/post/README.md rename to packages/postinstall/README.md diff --git a/packages/post/package.json b/packages/postinstall/package.json similarity index 100% rename from packages/post/package.json rename to packages/postinstall/package.json diff --git a/packages/resolver/package.json b/packages/resolver/package.json index f7aae6cae8a3f12ca103cfcccce7b7f60ac9507f..653143be24b5f72a155cabf06ea25ddf13792b8f 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-resolver", - "version": "0.8.0", + "version": "0.8.7", "description": "This is NOT for general use, please do not install it directly. This module is part of the jsonql tools supporting modules.", "main": "index.js", "files": [ @@ -22,16 +22,17 @@ "url": "https://gitee.com/to1source/jsonql/issues" }, "dependencies": { + "debug": "^4.1.1", "jsonql-constants": "^1.8.3", "jsonql-errors": "^1.1.3", - "jsonql-jwt": "^1.3.1", - "jsonql-node-client": "^1.1.7", - "jsonql-params-validator": "^1.4.8", - "jsonql-utils": "^0.4.9", + "jsonql-jwt": "^1.3.2", + "jsonql-node-client": "^1.1.8", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.6.10", "lodash.merge": "^4.6.2" }, "devDependencies": { - "ava": "^2.3.0", + "ava": "^2.4.0", "jsonql-contract": "^1.7.8", "jsonql-koa": "^1.3.8", "server-io-core": "^1.2.0" diff --git a/packages/resolver/src/client/inject-node-clients.js b/packages/resolver/src/client/inject-node-clients.js index c5269be4d23231552d16a5016c287b9a6d09f2f9..6c1aaeb2d4dbd3277e071ef8d027847f9ebb3586 100644 --- a/packages/resolver/src/client/inject-node-clients.js +++ b/packages/resolver/src/client/inject-node-clients.js @@ -1,6 +1,6 @@ // injecting the clients into the resolver const { injectToFn } = require('jsonql-utils') -const CLIENT_PROP_NAME = require('jsonql-constants') +const { CLIENT_PROP_NAME } = require('jsonql-constants') const { getDebug } = require('../utils') const debug = getDebug(`inject-node-clients`) diff --git a/packages/resolver/src/handle-auth-methods.js b/packages/resolver/src/handle-auth-methods.js index eeef537bea0bf0b0976893147c3bee178b5d1438..6b73a38efed78517c966eb053c768a82c6b2a682 100644 --- a/packages/resolver/src/handle-auth-methods.js +++ b/packages/resolver/src/handle-auth-methods.js @@ -1,3 +1,4 @@ +// Auth methods handler const { getDebug } = require('./utils') const searchResolvers = require('./search-resolvers') const validateAndCall = require('./validate-and-call') diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index e487d2cb5d9460886ee0578dca882280df385f6f..10ea6a5af8fb23b816d62836349b851d9c912ab8 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -6,7 +6,7 @@ const { JsonqlResolverAppError, JsonqlValidationError, JsonqlAuthorisationError, - getErrorNameByInstance, + getErrorNameByInstanceWithDefault, UNKNOWN_ERROR } = require('jsonql-errors') // @TODO this should move to the jsonql-utils! @@ -99,15 +99,12 @@ const resolverRenderHandler = async (ctx, type, opts, contract) => { return renderHandler(ctx, packResult(result)) } catch (e) { debug('resolveMethod error', e) - let errorName = getErrorNameByInstance([ + let errorName = getErrorNameByInstanceWithDefault([ JsonqlResolverNotFoundError, JsonqlAuthorisationError, JsonqlValidationError, JsonqlResolverAppError ], e) - if (errorName === UNKNOWN_ERROR) { - errorName = 'JsonqlError'; - } return ctxErrorHandler(ctx, errorName, e) } diff --git a/packages/resolver/src/search-resolvers.js b/packages/resolver/src/search-resolvers.js index 67706a6b1a494b1d37e35942b3d60714b48f35c1..3f1df90f19a6ce317b38197e2a8a9377c6d66529 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -1,5 +1,5 @@ // search for the resolver location -const { join } = require('path') +// const { join } = require('path') const { JsonqlResolverNotFoundError } = require('jsonql-errors') const { getPathToFn, findFromContract } = require('jsonql-utils') diff --git a/packages/resolver/src/utils.js b/packages/resolver/src/utils.js index 96f0ec8401cbb09fb78e93f8823cd9be29a43022..b92db0c5485dc983cfbe6cc0eb63c949411fde79 100644 --- a/packages/resolver/src/utils.js +++ b/packages/resolver/src/utils.js @@ -1,9 +1,9 @@ -const { getDebug } = require('jsonql-utils') +const debug = require('debug') const MODULE_NAME = 'jsonql-resolver' module.exports = { getDebug: function(name) { - return getDebug(name, MODULE_NAME) + return debug(MODULE_NAME).extend(name) } } diff --git a/packages/resolver/src/validate-and-call.js b/packages/resolver/src/validate-and-call.js index 2b596e04d8167c8e5faba2a140a0c5b9cfbb8c35..254a6963f325e89a179ff0b2f890d84a101ae723 100644 --- a/packages/resolver/src/validate-and-call.js +++ b/packages/resolver/src/validate-and-call.js @@ -59,12 +59,13 @@ module.exports = function validateAndCall(fn, args, contract, type, name, opts) debug(`validation failed on client side`, args, params) throw new JsonqlValidationError(name, errors) } - // fn.apply(null, args) + return Promise .resolve(Reflect.apply(fn, null, args)) .then(applyJwtMethod(type, name, opts, contract)) + /* we will debug this from the other side .catch(e => { debug(`error throw inside the promise`, e) throw e; - }) + }) */ } diff --git a/packages/utils/README.md b/packages/utils/README.md index 8a59c0956ca7116abbd91f8020194292ba54d69e..fea2ab7b1322b059ec47f95f08e815239345695e 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -43,6 +43,10 @@ Please check [jsonql](https://jsonql.js.org) for more information. - ctxErrorHandler - forbiddenHandler +## Breaking change (0.6.4) + +The `module` now only export the browser used modules. The `main` field comes with everything including all the node.js one. + --- ISC diff --git a/packages/utils/browser.js b/packages/utils/browser.js new file mode 100644 index 0000000000000000000000000000000000000000..fa8399ac7aabef661236cc520ed75fa7083053ac --- /dev/null +++ b/packages/utils/browser.js @@ -0,0 +1,2 @@ +!function(r,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((r=r||self).jsonqlUtils={})}(this,(function(r){"use strict";var t=Array.isArray,e="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n="object"==typeof e&&e&&e.Object===Object&&e,o="object"==typeof self&&self&&self.Object===Object&&self,u=(n||o||Function("return this")()).Symbol,a=Object.prototype,i=a.hasOwnProperty,c=a.toString,f=u?u.toStringTag:void 0;var s=Object.prototype.toString;var l="[object Null]",d="[object Undefined]",p=u?u.toStringTag:void 0;function v(r){return null==r?void 0===r?d:l:p&&p in Object(r)?function(r){var t=i.call(r,f),e=r[f];try{r[f]=void 0;var n=!0}catch(r){}var o=c.call(r);return n&&(t?r[f]=e:delete r[f]),o}(r):function(r){return s.call(r)}(r)}var y,g,h=(y=Object.getPrototypeOf,g=Object,function(r){return y(g(r))});function b(r){return null!=r&&"object"==typeof r}var m="[object Object]",j=Function.prototype,O=Object.prototype,w=j.toString,P=O.hasOwnProperty,S=w.call(Object);function N(r){if(!b(r)||v(r)!=m)return!1;var t=h(r);if(null===t)return!0;var e=P.call(t,"constructor")&&t.constructor;return"function"==typeof e&&e instanceof e&&w.call(e)==S}var _="[object Symbol]";var k=1/0,E=u?u.prototype:void 0,F=E?E.toString:void 0;function x(r){if("string"==typeof r)return r;if(t(r))return function(r,t){for(var e=-1,n=null==r?0:r.length,o=Array(n);++e=n?r:function(r,t,e){var n=-1,o=r.length;t<0&&(t=-t>o?0:o+t),(e=e>o?o:e)<0&&(e+=o),o=t>e?0:e-t>>>0,t>>>=0;for(var u=Array(o);++n-1;);return e}(o,u),function(r,t){for(var e=r.length;e--&&T(t,r[e],0)>-1;);return e}(o,u)+1).join("")}var L="[object String]";function Z(r){return"string"==typeof r||!t(r)&&b(r)&&v(r)==L}var G=function(r,t){return!!r.filter((function(r){return r===t})).length},W=function(r,t){var e=Object.keys(r);return G(e,t)},X=function(r){void 0===r&&(r=!1);var t=Date.now();return r?Math.floor(t/1e3):t},Y=function(r,t){var e=[];for(var n in t)e.push([n,t[n]].join("="));return[r,e.join("&")].join("?")},rr=function(){return{_cb:X()}},tr="query",er="mutation",nr="socket",or="payload",ur="condition",ar="resolverName",ir="args",cr=["POST","PUT"],fr=function(){try{if(window||document)return!0}catch(r){}return!1},sr=function(){try{if(!fr()&&e)return!0}catch(r){}return!1};var lr=function(r){function t(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];r.apply(this,t)}return r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t,t.where=function(){return fr()?"browser":sr()?"node":"unknown"},t}(Error),dr=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 404},e.name.get=function(){return"JsonqlResolverNotFoundError"},Object.defineProperties(t,e),t}(lr),pr=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(t,e),t}(lr),vr=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return-1},Object.defineProperties(t,e),t}(lr);function yr(r){return N(r)&&(W(r,tr)||W(r,er)||W(r,nr))}function gr(r){return!!W(r,"socket")&&r.socket}var hr=function(r){return Z(r)?JSON.parse(r):r},br=function(r){var t;return(t={})[ir]=r,t};function mr(r){return Object.keys(r)[0]}function jr(r,e,n){var o;if(void 0===e&&(e=[]),void 0===n&&(n=!1),Z(r)&&t(e)){var u=br(e);return!0===n?u:((o={})[r]=u,o)}throw new pr("[createQuery] expect resolverName to be string and args to be array!",{resolverName:r,args:e})}function Or(r,t,e,n){var o;void 0===e&&(e={}),void 0===n&&(n=!1);var u={};if(u[or]=t,u[ur]=e,!0===n)return u;if(Z(r))return(o={})[r]=u,o;throw new pr("[createMutation] expect resolverName to be string!",{resolverName:r,payload:t,condition:e})}function wr(r,t){var e;if(r&&N(t)){var n=t[r];if(n[ir])return(e={})[ar]=r,e[ir]=n[ir],e}return!1}function Pr(r,t){var e=hr(r),n=mr(e);return Reflect.apply(t,null,[n,e])}function Sr(r,t){var e;if(r&&N(t)){var n=t[r];if(n)return(e={})[ar]=r,e[or]=n[or],e[ur]=n[ur],e}return!1}var Nr=yr;r.VERSION="0.6.10",r.cacheBurst=rr,r.cacheBurstUrl=function(r){return Y(r,rr())},r.chainFns=function(r){for(var t=[],e=arguments.length-1;e-- >0;)t[e]=arguments[e+1];return function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return t.reduce((function(r,t){return Reflect.apply(t,null,[r])}),Reflect.apply(r,null,e))}},r.chainPromises=function(r){return r.reduce((function(r,t){return r.then((function(r){return t.then((function(t){return r.concat([t])}))}))}),Promise.resolve([]))},r.checkIsContract=yr,r.createEvt=function(){for(var r=[],t=arguments.length;t--;)r[t]=arguments[t];return r.join("_")},r.createMutation=Or,r.createMutationStr=function(r,t,e,n){return void 0===e&&(e={}),void 0===n&&(n=!1),JSON.stringify(Or(r,t,e,n))},r.createQuery=jr,r.createQueryStr=function(r,t,e){return void 0===t&&(t=[]),void 0===e&&(e=!1),JSON.stringify(jr(r,t,e))},r.dasherize=function(r){return K(r).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},r.extractArgsFromPayload=function(r,t){switch(t){case tr:return r[ir];case er:return[r[or],r[ur]];default:throw new vr("Unknown "+t+" to extract argument from!")}},r.extractParamsFromContract=function(r,t,e){try{var n=r[t][e];if(!n)throw new dr(e,t);return n}catch(r){throw new dr(e,r)}},r.extractSocketPart=gr,r.formatPayload=br,r.getCallMethod=function(r){switch(!0){case r===cr[0]:return tr;case r===cr[1]:return er;default:return!1}},r.getConfigValue=function(r,t){return t&&N(t)&&r in t?t[r]:void 0},r.getMutationFromArgs=Sr,r.getMutationFromPayload=function(r){var t=Pr(r,Sr);if(!1!==t)return t;throw new pr("[getMutationArgs] Payload is malformed!",r)},r.getNameFromPayload=mr,r.getQueryFromArgs=wr,r.getQueryFromPayload=function(r){var t=Pr(r,wr);if(!1!==t)return t;throw new pr("[getQueryArgs] Payload is malformed!",r)},r.groupByNamespace=function(r,t){void 0===t&&(t=!1);var e=gr(r);if(!1===e){if(t)return r;throw new vr("socket not found in contract!")}var n,o={},u=0;for(var a in e){var i=e[a],c=i.namespace;c&&(o[c]||(++u,o[c]={}),o[c][a]=i,n||i.public&&(n=c))}return{size:u,nspSet:o,publicNamespace:n}},r.inArray=G,r.injectToFn=function(r,t,e,n){void 0===n&&(n=!1);var o=Object.getOwnPropertyDescriptor(r,t);return!1===n&&void 0!==o?r:(Object.defineProperty(r,t,{value:e,writable:n}),r)},r.isContract=Nr,r.isKeyInObject=W,r.isNotEmpty=function(r){return void 0!==r&&!1!==r&&null!==r&&""!==K(r)},r.objDefineProps=function(r,t,e,n){return void 0===n&&(n=null),void 0===Object.getOwnPropertyDescriptor(r,t)&&Object.defineProperty(r,t,{set:e,get:null===n?function(){return null}:n}),r},r.packError=function(r,t,e,n){var o;return void 0===t&&(t="JsonqlError"),void 0===e&&(e=500),void 0===n&&(n=""),JSON.stringify(((o={}).error={detail:r,className:t,statusCode:e,message:n},o))},r.packResult=function(r){var t;return JSON.stringify(((t={}).data=r,t))},r.resultHandler=function(r){return W(r,"data")&&!W(r,"error")?r.data:r},r.timestamp=X,r.toPayload=hr,r.urlParams=Y,Object.defineProperty(r,"__esModule",{value:!0})})); +//# sourceMappingURL=browser.js.map diff --git a/packages/utils/browser.js.map b/packages/utils/browser.js.map new file mode 100644 index 0000000000000000000000000000000000000000..585d1c8d5cb1879d823c553c7c19ac0228632bdc --- /dev/null +++ b/packages/utils/browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"browser.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/debug.js b/packages/utils/debug.js new file mode 100644 index 0000000000000000000000000000000000000000..b50b81604a0903991cbf3ff4a35bf6f2f28174c5 --- /dev/null +++ b/packages/utils/debug.js @@ -0,0 +1,12 @@ +import debug from 'debug' + +/** + * @param {string} name the name part after the : + * @param {string} baseName the base before the : + */ +export const getDebug = (name, baseName = 'jsonql') => { + try { + return debug(baseName).extend(name) + } catch(e) {} + return () => {} // just return a fake function +} diff --git a/packages/utils/index.js b/packages/utils/index.js new file mode 100644 index 0000000000000000000000000000000000000000..13adde5b48d1fdcda42c9941e623b5db6761eea4 --- /dev/null +++ b/packages/utils/index.js @@ -0,0 +1,131 @@ +// this is a new one that only include the browser usable modules +// and the for node only modules +// then the main will include this one instead, then when run the build script +// we won't get those missing node modules blah blah problems +import { + // chain-fns + chainFns, + chainPromises, + // contract + extractArgsFromPayload, + extractParamsFromContract, + checkIsContract, + extractSocketPart, + groupByNamespace, + isContract, // alias + // generic + inArray, + isKeyInObject, + dasherize, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, + getConfigValue, + isNotEmpty, + // params-api + toPayload, + formatPayload, + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload, + // objectDefineProp + injectToFn, + objDefineProps, + // results + getCallMethod, + packResult, + packError, + resultHandler, + VERSION +} from './module' +import { buff } from './src/jwt' +// node import +import { replaceErrors, printError } from './src/node-error' +import { findFromContract } from './src/node-find-from-contract' +import { + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler +} from './src/node-koa' +import { + getDocLen, + headerParser, + isHeaderPresent, + getPathToFn +} from './src/node-middleware' + +// export +export { + // node export + buff, + findFromContract, + // errors + replaceErrors, + printError, + // koa + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler, + // middleware + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError, + resultHandler, + // chain-fns + chainFns, + chainPromises, + // contract + extractArgsFromPayload, + extractParamsFromContract, + checkIsContract, + extractSocketPart, + groupByNamespace, + isContract, // alias + // generic + inArray, + isKeyInObject, + dasherize, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, + getConfigValue, + isNotEmpty, + // params-api + toPayload, + formatPayload, + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload, + // objectDefineProp + injectToFn, + objDefineProps, + VERSION +} diff --git a/packages/utils/main.js b/packages/utils/main.js index 17d9c0d6dca64aff2e79cb6a7931a94c8d7ba6bd..d4c195b26ede7831036c466372a19f3e8bf0be8b 100644 --- a/packages/utils/main.js +++ b/packages/utils/main.js @@ -1,3 +1,2 @@ -// export for CJS modules using esm modules -require = require('esm')(module) -module.exports = require('./es.js') +"use strict";function _interopDefault(r){return r&&"object"==typeof r&&"default"in r?r.default:r}Object.defineProperty(exports,"__esModule",{value:!0});var fs=_interopDefault(require("fs")),path=require("path"),chainFns=function(r){for(var t=[],e=arguments.length-1;e-- >0;)t[e]=arguments[e+1];return function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return t.reduce((function(r,t){return Reflect.apply(t,null,[r])}),Reflect.apply(r,null,e))}};function chainPromises(r){return r.reduce((function(r,t){return r.then((function(r){return t.then((function(t){return r.concat([t])}))}))}),Promise.resolve([]))}function objDefineProps(r,t,e,n){return void 0===n&&(n=null),void 0===Object.getOwnPropertyDescriptor(r,t)&&Object.defineProperty(r,t,{set:e,get:null===n?function(){return null}:n}),r}function injectToFn(r,t,e,n){void 0===n&&(n=!1);var o=Object.getOwnPropertyDescriptor(r,t);return!1===n&&void 0!==o?r:(Object.defineProperty(r,t,{value:e,writable:n}),r)}var isArray=Array.isArray,global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;function getRawTag(r){var t=hasOwnProperty.call(r,symToStringTag),e=r[symToStringTag];try{r[symToStringTag]=void 0;var n=!0}catch(r){}var o=nativeObjectToString.call(r);return n&&(t?r[symToStringTag]=e:delete r[symToStringTag]),o}var objectProto$1=Object.prototype,nativeObjectToString$1=objectProto$1.toString;function objectToString(r){return nativeObjectToString$1.call(r)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag$1=Symbol?Symbol.toStringTag:void 0;function baseGetTag(r){return null==r?void 0===r?undefinedTag:nullTag:symToStringTag$1&&symToStringTag$1 in Object(r)?getRawTag(r):objectToString(r)}function overArg(r,t){return function(e){return r(t(e))}}var getPrototype=overArg(Object.getPrototypeOf,Object);function isObjectLike(r){return null!=r&&"object"==typeof r}var objectTag="[object Object]",funcProto=Function.prototype,objectProto$2=Object.prototype,funcToString=funcProto.toString,hasOwnProperty$1=objectProto$2.hasOwnProperty,objectCtorString=funcToString.call(Object);function isPlainObject(r){if(!isObjectLike(r)||baseGetTag(r)!=objectTag)return!1;var t=getPrototype(r);if(null===t)return!0;var e=hasOwnProperty$1.call(t,"constructor")&&t.constructor;return"function"==typeof e&&e instanceof e&&funcToString.call(e)==objectCtorString}function arrayMap(r,t){for(var e=-1,n=null==r?0:r.length,o=Array(n);++eo?0:o+t),(e=e>o?o:e)<0&&(e+=o),o=t>e?0:e-t>>>0,t>>>=0;for(var i=Array(o);++n=n?r:baseSlice(r,t,e)}function baseFindIndex(r,t,e,n){for(var o=r.length,i=e+(n?1:-1);n?i--:++i-1;);return e}function charsStartIndex(r,t){for(var e=-1,n=r.length;++e-1;);return e}function asciiToArray(r){return r.split("")}var rsAstralRange="\\ud800-\\udfff",rsComboMarksRange="\\u0300-\\u036f",reComboHalfMarksRange="\\ufe20-\\ufe2f",rsComboSymbolsRange="\\u20d0-\\u20ff",rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsVarRange="\\ufe0e\\ufe0f",rsZWJ="\\u200d",reHasUnicode=RegExp("["+rsZWJ+rsAstralRange+rsComboRange+rsVarRange+"]");function hasUnicode(r){return reHasUnicode.test(r)}var rsAstralRange$1="\\ud800-\\udfff",rsComboMarksRange$1="\\u0300-\\u036f",reComboHalfMarksRange$1="\\ufe20-\\ufe2f",rsComboSymbolsRange$1="\\u20d0-\\u20ff",rsComboRange$1=rsComboMarksRange$1+reComboHalfMarksRange$1+rsComboSymbolsRange$1,rsVarRange$1="\\ufe0e\\ufe0f",rsAstral="["+rsAstralRange$1+"]",rsCombo="["+rsComboRange$1+"]",rsFitz="\\ud83c[\\udffb-\\udfff]",rsModifier="(?:"+rsCombo+"|"+rsFitz+")",rsNonAstral="[^"+rsAstralRange$1+"]",rsRegional="(?:\\ud83c[\\udde6-\\uddff]){2}",rsSurrPair="[\\ud800-\\udbff][\\udc00-\\udfff]",rsZWJ$1="\\u200d",reOptMod=rsModifier+"?",rsOptVar="["+rsVarRange$1+"]?",rsOptJoin="(?:"+rsZWJ$1+"(?:"+[rsNonAstral,rsRegional,rsSurrPair].join("|")+")"+rsOptVar+reOptMod+")*",rsSeq=rsOptVar+reOptMod+rsOptJoin,rsSymbol="(?:"+[rsNonAstral+rsCombo+"?",rsCombo,rsRegional,rsSurrPair,rsAstral].join("|")+")",reUnicode=RegExp(rsFitz+"(?="+rsFitz+")|"+rsSymbol+rsSeq,"g");function unicodeToArray(r){return r.match(reUnicode)||[]}function stringToArray(r){return hasUnicode(r)?unicodeToArray(r):asciiToArray(r)}function toString(r){return null==r?"":baseToString(r)}var reTrim=/^\s+|\s+$/g;function trim(r,t,e){if((r=toString(r))&&(e||void 0===t))return r.replace(reTrim,"");if(!r||!(t=baseToString(t)))return r;var n=stringToArray(r),o=stringToArray(t);return castSlice(n,charsStartIndex(n,o),charsEndIndex(n,o)+1).join("")}var stringTag="[object String]";function isString(r){return"string"==typeof r||!isArray(r)&&isObjectLike(r)&&baseGetTag(r)==stringTag}var inArray=function(r,t){return!!r.filter((function(r){return r===t})).length},isKeyInObject=function(r,t){var e=Object.keys(r);return inArray(e,t)},createEvt=function(){for(var r=[],t=arguments.length;t--;)r[t]=arguments[t];return r.join("_")},timestamp=function(r){void 0===r&&(r=!1);var t=Date.now();return r?Math.floor(t/1e3):t},urlParams=function(r,t){var e=[];for(var n in t)e.push([n,t[n]].join("="));return[r,e.join("&")].join("?")},cacheBurstUrl=function(r){return urlParams(r,cacheBurst())},cacheBurst=function(){return{_cb:timestamp()}},dasherize=function(r){return trim(r).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},getConfigValue=function(r,t){return t&&isPlainObject(t)&&r in t?t[r]:void 0},isNotEmpty=function(r){return void 0!==r&&!1!==r&&null!==r&&""!==trim(r)},EXT="js",DATA_KEY="data",ERROR_KEY="error",CONTENT_TYPE="application/vnd.api+json",QUERY_NAME="query",MUTATION_NAME="mutation",SOCKET_NAME="socket",PAYLOAD_PARAM_NAME="payload",CONDITION_PARAM_NAME="condition",RESOLVER_PARAM_NAME="resolverName",QUERY_ARG_NAME="args",API_REQUEST_METHODS=["POST","PUT"],INDEX_KEY="index",NO_ERROR_MSG="No message",NO_STATUS_CODE=-1,BASE64_FORMAT="base64",SUCCESS_STATUS=200,FORBIDDEN_STATUS=403;function getErrorByStatus(r,t){switch(void 0===t&&(t=!1),r){case 401:return t?"JsonqlContractAuthError":"JsonqlAuthorisationError";case 403:return"JsonqlForbiddenError";case 404:return"JsonqlResolverNotFoundError";case 406:return"Jsonql406Error";case 500:return"Jsonql500Error";default:return"JsonqlError"}}var Jsonql406Error=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 406},e.name.get=function(){return"Jsonql406Error"},Object.defineProperties(t,e),t}(Error),Jsonql500Error=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 500},e.name.get=function(){return"Jsonql500Error"},Object.defineProperties(t,e),t}(Error),JsonqlAuthorisationError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 401},e.name.get=function(){return"JsonqlAuthorisationError"},Object.defineProperties(t,e),t}(Error),JsonqlContractAuthError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 401},e.name.get=function(){return"JsonqlContractAuthError"},Object.defineProperties(t,e),t}(Error),JsonqlResolverAppError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 500},e.name.get=function(){return"JsonqlResolverAppError"},Object.defineProperties(t,e),t}(Error),isBrowser=function(){try{if(window||document)return!0}catch(r){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(r){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(r){function t(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];r.apply(this,t)}return r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t,t.where=function(){return whereAmI()},t}(Error),JsonqlResolverNotFoundError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={statusCode:{configurable:!0},name:{configurable:!0}};return e.statusCode.get=function(){return 404},e.name.get=function(){return"JsonqlResolverNotFoundError"},Object.defineProperties(t,e),t}(JsonqlBaseError),JsonqlEnumError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(t,e),t}(Error),JsonqlTypeError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(t,e),t}(Error),JsonqlCheckerError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,r.captureStackTrace&&r.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(t,e),t}(Error),JsonqlValidationError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(t,e),t}(JsonqlBaseError),JsonqlError=function(r){function t(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];r.apply(this,e),this.message=e[0],this.detail=e[1],this.className=t.name,Error.captureStackTrace&&Error.captureStackTrace(this,t)}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return NO_STATUS_CODE},Object.defineProperties(t,e),t}(JsonqlBaseError),JsonqlServerError=function(r){function t(e,n){r.call(this,n),this.statusCode=e,this.className=t.name}r&&(t.__proto__=r),t.prototype=Object.create(r&&r.prototype),t.prototype.constructor=t;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlServerError"},Object.defineProperties(t,e),t}(Error),errors=Object.freeze({Jsonql406Error:Jsonql406Error,Jsonql500Error:Jsonql500Error,JsonqlAuthorisationError:JsonqlAuthorisationError,JsonqlContractAuthError:JsonqlContractAuthError,JsonqlResolverAppError:JsonqlResolverAppError,JsonqlResolverNotFoundError:JsonqlResolverNotFoundError,JsonqlEnumError:JsonqlEnumError,JsonqlTypeError:JsonqlTypeError,JsonqlCheckerError:JsonqlCheckerError,JsonqlValidationError:JsonqlValidationError,JsonqlError:JsonqlError,JsonqlServerError:JsonqlServerError}),JsonqlError$1=JsonqlError,isKeyInObject$1=function(r,t){return!!Object.keys(r).filter((function(r){return t===r})).length};function clientErrorsHandler(r){if(isKeyInObject$1(r,"error")){var t=r.error,e=t.className,n=t.name,o=e||n,i=t.message||NO_ERROR_MSG,a=t.detail||t;if(o&&errors[o])throw new errors[e](i,a);throw new JsonqlError$1(i,a)}return r}var UNKNOWN_ERROR="unknown";function mapErrToName(r,t){return r.filter((function(r){return t instanceof r})).map((function(r){return r.name}))}function getErrorNameByInstance(r,t){var e=mapErrToName(r,t);return e.length?e[0]:UNKNOWN_ERROR}function getErrorNameByInstanceWithDefault(r,t){var e=getErrorNameByInstance(r,t);return e===UNKNOWN_ERROR?"JsonqlError":e}function finalCatch(r){if(Array.isArray(r))throw new JsonqlValidationError("",r);var t=r.message||NO_ERROR_MSG,e=r.detail||r;switch(!0){case r instanceof Jsonql406Error:throw new Jsonql406Error(t,e);case r instanceof Jsonql500Error:throw new Jsonql500Error(t,e);case r instanceof JsonqlAuthorisationError:throw new JsonqlAuthorisationError(t,e);case r instanceof JsonqlContractAuthError:throw new JsonqlContractAuthError(t,e);case r instanceof JsonqlResolverAppError:throw new JsonqlResolverAppError(t,e);case r instanceof JsonqlResolverNotFoundError:throw new JsonqlResolverNotFoundError(t,e);case r instanceof JsonqlEnumError:throw new JsonqlEnumError(t,e);case r instanceof JsonqlTypeError:throw new JsonqlTypeError(t,e);case r instanceof JsonqlCheckerError:throw new JsonqlCheckerError(t,e);case r instanceof JsonqlValidationError:throw new JsonqlValidationError(t,e);case r instanceof JsonqlServerError:throw new JsonqlServerError(t,e);default:throw new JsonqlError(t,e)}}var JSONQL_ERRORS_INFO="__PLACEHOLDER__",jsonqlErrors=Object.freeze({JSONQL_ERRORS_INFO:JSONQL_ERRORS_INFO,UNKNOWN_ERROR:UNKNOWN_ERROR,getErrorByStatus:getErrorByStatus,clientErrorsHandler:clientErrorsHandler,finalCatch:finalCatch,getErrorNameByInstance:getErrorNameByInstance,getErrorNameByInstanceWithDefault:getErrorNameByInstanceWithDefault,Jsonql406Error:Jsonql406Error,Jsonql500Error:Jsonql500Error,JsonqlAuthorisationError:JsonqlAuthorisationError,JsonqlContractAuthError:JsonqlContractAuthError,JsonqlResolverAppError:JsonqlResolverAppError,JsonqlResolverNotFoundError:JsonqlResolverNotFoundError,JsonqlEnumError:JsonqlEnumError,JsonqlTypeError:JsonqlTypeError,JsonqlCheckerError:JsonqlCheckerError,JsonqlValidationError:JsonqlValidationError,JsonqlError:JsonqlError,JsonqlServerError:JsonqlServerError});function checkIsContract(r){return isPlainObject(r)&&(isKeyInObject(r,QUERY_NAME)||isKeyInObject(r,MUTATION_NAME)||isKeyInObject(r,SOCKET_NAME))}function extractSocketPart(r){return!!isKeyInObject(r,"socket")&&r.socket}function groupByNamespace(r,t){void 0===t&&(t=!1);var e=extractSocketPart(r);if(!1===e){if(t)return r;throw new JsonqlError("socket not found in contract!")}var n,o={},i=0;for(var a in e){var s=e[a],u=s.namespace;u&&(o[u]||(++i,o[u]={}),o[u][a]=s,n||s.public&&(n=u))}return{size:i,nspSet:o,publicNamespace:n}}function extractArgsFromPayload(r,t){switch(t){case QUERY_NAME:return r[QUERY_ARG_NAME];case MUTATION_NAME:return[r[PAYLOAD_PARAM_NAME],r[CONDITION_PARAM_NAME]];default:throw new JsonqlError("Unknown "+t+" to extract argument from!")}}function extractParamsFromContract(r,t,e){try{var n=r[t][e];if(!n)throw new JsonqlResolverNotFoundError(e,t);return n}catch(r){throw new JsonqlResolverNotFoundError(e,r)}}var toPayload=function(r){return isString(r)?JSON.parse(r):r},formatPayload=function(r){var t;return(t={})[QUERY_ARG_NAME]=r,t};function getNameFromPayload(r){return Object.keys(r)[0]}function createQuery(r,t,e){var n;if(void 0===t&&(t=[]),void 0===e&&(e=!1),isString(r)&&isArray(t)){var o=formatPayload(t);return!0===e?o:((n={})[r]=o,n)}throw new JsonqlValidationError("[createQuery] expect resolverName to be string and args to be array!",{resolverName:r,args:t})}function createQueryStr(r,t,e){return void 0===t&&(t=[]),void 0===e&&(e=!1),JSON.stringify(createQuery(r,t,e))}function createMutation(r,t,e,n){var o;void 0===e&&(e={}),void 0===n&&(n=!1);var i={};if(i[PAYLOAD_PARAM_NAME]=t,i[CONDITION_PARAM_NAME]=e,!0===n)return i;if(isString(r))return(o={})[r]=i,o;throw new JsonqlValidationError("[createMutation] expect resolverName to be string!",{resolverName:r,payload:t,condition:e})}function createMutationStr(r,t,e,n){return void 0===e&&(e={}),void 0===n&&(n=!1),JSON.stringify(createMutation(r,t,e,n))}function getQueryFromArgs(r,t){var e;if(r&&isPlainObject(t)){var n=t[r];if(n[QUERY_ARG_NAME])return(e={})[RESOLVER_PARAM_NAME]=r,e[QUERY_ARG_NAME]=n[QUERY_ARG_NAME],e}return!1}function processPayload(r,t){var e=toPayload(r),n=getNameFromPayload(e);return Reflect.apply(t,null,[n,e])}function getQueryFromPayload(r){var t=processPayload(r,getQueryFromArgs);if(!1!==t)return t;throw new JsonqlValidationError("[getQueryArgs] Payload is malformed!",r)}function getMutationFromArgs(r,t){var e;if(r&&isPlainObject(t)){var n=t[r];if(n)return(e={})[RESOLVER_PARAM_NAME]=r,e[PAYLOAD_PARAM_NAME]=n[PAYLOAD_PARAM_NAME],e[CONDITION_PARAM_NAME]=n[CONDITION_PARAM_NAME],e}return!1}function getMutationFromPayload(r){var t=processPayload(r,getMutationFromArgs);if(!1!==t)return t;throw new JsonqlValidationError("[getMutationArgs] Payload is malformed!",r)}var getCallMethod=function(r){var t=API_REQUEST_METHODS[0],e=API_REQUEST_METHODS[1];switch(!0){case r===t:return QUERY_NAME;case r===e:return MUTATION_NAME;default:return!1}},packResult=function(r){var t;return JSON.stringify(((t={})[DATA_KEY]=r,t))},packError=function(r,t,e,n){var o;return void 0===t&&(t="JsonqlError"),void 0===e&&(e=500),void 0===n&&(n=""),JSON.stringify(((o={})[ERROR_KEY]={detail:r,className:t,statusCode:e,message:n},o))},resultHandler=function(r){return isKeyInObject(r,DATA_KEY)&&!isKeyInObject(r,ERROR_KEY)?r[DATA_KEY]:r},isContract=checkIsContract,VERSION="0.6.10",lookup=[],revLookup=[],Arr="undefined"!=typeof Uint8Array?Uint8Array:Array,inited=!1;function init(){inited=!0;for(var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,e=r.length;t0)throw new Error("Invalid string. Length must be a multiple of 4");i="="===r[s-2]?2:"="===r[s-1]?1:0,a=new Arr(3*s/4-i),n=i>0?s-4:s;var u=0;for(t=0,e=0;t>16&255,a[u++]=o>>8&255,a[u++]=255&o;return 2===i?(o=revLookup[r.charCodeAt(t)]<<2|revLookup[r.charCodeAt(t+1)]>>4,a[u++]=255&o):1===i&&(o=revLookup[r.charCodeAt(t)]<<10|revLookup[r.charCodeAt(t+1)]<<4|revLookup[r.charCodeAt(t+2)]>>2,a[u++]=o>>8&255,a[u++]=255&o),a}function tripletToBase64(r){return lookup[r>>18&63]+lookup[r>>12&63]+lookup[r>>6&63]+lookup[63&r]}function encodeChunk(r,t,e){for(var n,o=[],i=t;is?s:a+16383));return 1===n?(t=r[e-1],o+=lookup[t>>2],o+=lookup[t<<4&63],o+="=="):2===n&&(t=(r[e-2]<<8)+r[e-1],o+=lookup[t>>10],o+=lookup[t>>4&63],o+=lookup[t<<2&63],o+="="),i.push(o),i.join("")}function read(r,t,e,n,o){var i,a,s=8*o-n-1,u=(1<>1,c=-7,l=e?o-1:0,h=e?-1:1,p=r[t+l];for(l+=h,i=p&(1<<-c)-1,p>>=-c,c+=s;c>0;i=256*i+r[t+l],l+=h,c-=8);for(a=i&(1<<-c)-1,i>>=-c,c+=n;c>0;a=256*a+r[t+l],l+=h,c-=8);if(0===i)i=1-f;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,n),i-=f}return(p?-1:1)*a*Math.pow(2,i-n)}function write(r,t,e,n,o,i){var a,s,u,f=8*i-o-1,c=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:i-1,g=n?1:-1,y=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=c):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+l>=1?h/u:h*Math.pow(2,1-l))*u>=2&&(a++,u/=2),a+l>=c?(s=0,a=c):a+l>=1?(s=(t*u-1)*Math.pow(2,o),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,o),a=0));o>=8;r[e+p]=255&s,p+=g,s/=256,o-=8);for(a=a<0;r[e+p]=255&a,p+=g,a/=256,f-=8);r[e+p-g]|=128*y}var toString$1={}.toString,isArray$1=Array.isArray||function(r){return"[object Array]"==toString$1.call(r)},INSPECT_MAX_BYTES=50;function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(r,t){if(kMaxLength()=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|r}function internalIsBuffer(r){return!(null==r||!r._isBuffer)}function byteLength(r,t){if(internalIsBuffer(r))return r.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(r)||r instanceof ArrayBuffer))return r.byteLength;"string"!=typeof r&&(r=""+r);var e=r.length;if(0===e)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return utf8ToBytes(r).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return base64ToBytes(r).length;default:if(n)return utf8ToBytes(r).length;t=(""+t).toLowerCase(),n=!0}}function slowToString(r,t,e){var n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(t>>>=0))return"";for(r||(r="utf8");;)switch(r){case"hex":return hexSlice(this,t,e);case"utf8":case"utf-8":return utf8Slice(this,t,e);case"ascii":return asciiSlice(this,t,e);case"latin1":case"binary":return latin1Slice(this,t,e);case"base64":return base64Slice(this,t,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,t,e);default:if(n)throw new TypeError("Unknown encoding: "+r);r=(r+"").toLowerCase(),n=!0}}function swap(r,t,e){var n=r[t];r[t]=r[e],r[e]=n}function bidirectionalIndexOf(r,t,e,n,o){if(0===r.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=o?0:r.length-1),e<0&&(e=r.length+e),e>=r.length){if(o)return-1;e=r.length-1}else if(e<0){if(!o)return-1;e=0}if("string"==typeof t&&(t=Buffer.from(t,n)),internalIsBuffer(t))return 0===t.length?-1:arrayIndexOf(r,t,e,n,o);if("number"==typeof t)return t&=255,Buffer.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(r,t,e):Uint8Array.prototype.lastIndexOf.call(r,t,e):arrayIndexOf(r,[t],e,n,o);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(r,t,e,n,o){var i,a=1,s=r.length,u=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(r.length<2||t.length<2)return-1;a=2,s/=2,u/=2,e/=2}function f(r,t){return 1===a?r[t]:r.readUInt16BE(t*a)}if(o){var c=-1;for(i=e;is&&(e=s-u),i=e;i>=0;i--){for(var l=!0,h=0;ho&&(n=o):n=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");n>i/2&&(n=i/2);for(var a=0;a239?4:f>223?3:f>191?2:1;if(o+l<=e)switch(l){case 1:f<128&&(c=f);break;case 2:128==(192&(i=r[o+1]))&&(u=(31&f)<<6|63&i)>127&&(c=u);break;case 3:i=r[o+1],a=r[o+2],128==(192&i)&&128==(192&a)&&(u=(15&f)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(c=u);break;case 4:i=r[o+1],a=r[o+2],s=r[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&f)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(c=u)}null===c?(c=65533,l=1):c>65535&&(c-=65536,n.push(c>>>10&1023|55296),c=56320|1023&c),n.push(c),o+=l}return decodeCodePointsArray(n)}Buffer.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer.poolSize=8192,Buffer._augment=function(r){return r.__proto__=Buffer.prototype,r},Buffer.from=function(r,t,e){return from(null,r,t,e)},Buffer.TYPED_ARRAY_SUPPORT&&(Buffer.prototype.__proto__=Uint8Array.prototype,Buffer.__proto__=Uint8Array),Buffer.alloc=function(r,t,e){return alloc(null,r,t,e)},Buffer.allocUnsafe=function(r){return allocUnsafe(null,r)},Buffer.allocUnsafeSlow=function(r){return allocUnsafe(null,r)},Buffer.isBuffer=isBuffer,Buffer.compare=function(r,t){if(!internalIsBuffer(r)||!internalIsBuffer(t))throw new TypeError("Arguments must be Buffers");if(r===t)return 0;for(var e=r.length,n=t.length,o=0,i=Math.min(e,n);o0&&(r=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(r+=" ... ")),""},Buffer.prototype.compare=function(r,t,e,n,o){if(!internalIsBuffer(r))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===e&&(e=r?r.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||e>r.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&t>=e)return 0;if(n>=o)return-1;if(t>=e)return 1;if(this===r)return 0;for(var i=(o>>>=0)-(n>>>=0),a=(e>>>=0)-(t>>>=0),s=Math.min(i,a),u=this.slice(n,o),f=r.slice(t,e),c=0;co)&&(e=o),r.length>0&&(e<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return hexWrite(this,r,t,e);case"utf8":case"utf-8":return utf8Write(this,r,t,e);case"ascii":return asciiWrite(this,r,t,e);case"latin1":case"binary":return latin1Write(this,r,t,e);case"base64":return base64Write(this,r,t,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,r,t,e);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},Buffer.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(r){var t=r.length;if(t<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,r);for(var e="",n=0;nn)&&(e=n);for(var o="",i=t;ie)throw new RangeError("Trying to access beyond buffer length")}function checkInt(r,t,e,n,o,i){if(!internalIsBuffer(r))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||tr.length)throw new RangeError("Index out of range")}function objectWriteUInt16(r,t,e,n){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(r.length-e,2);o>>8*(n?o:1-o)}function objectWriteUInt32(r,t,e,n){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(r.length-e,4);o>>8*(n?o:3-o)&255}function checkIEEE754(r,t,e,n,o,i){if(e+n>r.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function writeFloat(r,t,e,n,o){return o||checkIEEE754(r,t,e,4),write(r,t,e,n,23,4),e+4}function writeDouble(r,t,e,n,o){return o||checkIEEE754(r,t,e,8),write(r,t,e,n,52,8),e+8}Buffer.prototype.slice=function(r,t){var e,n=this.length;if((r=~~r)<0?(r+=n)<0&&(r=0):r>n&&(r=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t0&&(o*=256);)n+=this[r+--t]*o;return n},Buffer.prototype.readUInt8=function(r,t){return t||checkOffset(r,1,this.length),this[r]},Buffer.prototype.readUInt16LE=function(r,t){return t||checkOffset(r,2,this.length),this[r]|this[r+1]<<8},Buffer.prototype.readUInt16BE=function(r,t){return t||checkOffset(r,2,this.length),this[r]<<8|this[r+1]},Buffer.prototype.readUInt32LE=function(r,t){return t||checkOffset(r,4,this.length),(this[r]|this[r+1]<<8|this[r+2]<<16)+16777216*this[r+3]},Buffer.prototype.readUInt32BE=function(r,t){return t||checkOffset(r,4,this.length),16777216*this[r]+(this[r+1]<<16|this[r+2]<<8|this[r+3])},Buffer.prototype.readIntLE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=this[r],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*t)),n},Buffer.prototype.readIntBE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=t,o=1,i=this[r+--n];n>0&&(o*=256);)i+=this[r+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},Buffer.prototype.readInt8=function(r,t){return t||checkOffset(r,1,this.length),128&this[r]?-1*(255-this[r]+1):this[r]},Buffer.prototype.readInt16LE=function(r,t){t||checkOffset(r,2,this.length);var e=this[r]|this[r+1]<<8;return 32768&e?4294901760|e:e},Buffer.prototype.readInt16BE=function(r,t){t||checkOffset(r,2,this.length);var e=this[r+1]|this[r]<<8;return 32768&e?4294901760|e:e},Buffer.prototype.readInt32LE=function(r,t){return t||checkOffset(r,4,this.length),this[r]|this[r+1]<<8|this[r+2]<<16|this[r+3]<<24},Buffer.prototype.readInt32BE=function(r,t){return t||checkOffset(r,4,this.length),this[r]<<24|this[r+1]<<16|this[r+2]<<8|this[r+3]},Buffer.prototype.readFloatLE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!0,23,4)},Buffer.prototype.readFloatBE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!1,23,4)},Buffer.prototype.readDoubleLE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!0,52,8)},Buffer.prototype.readDoubleBE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!1,52,8)},Buffer.prototype.writeUIntLE=function(r,t,e,n){(r=+r,t|=0,e|=0,n)||checkInt(this,r,t,e,Math.pow(2,8*e)-1,0);var o=1,i=0;for(this[t]=255&r;++i=0&&(i*=256);)this[t+o]=r/i&255;return t+e},Buffer.prototype.writeUInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,255,0),Buffer.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),this[t]=255&r,t+1},Buffer.prototype.writeUInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer.prototype.writeUInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer.prototype.writeUInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t+3]=r>>>24,this[t+2]=r>>>16,this[t+1]=r>>>8,this[t]=255&r):objectWriteUInt32(this,r,t,!0),t+4},Buffer.prototype.writeUInt32BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=r>>>24,this[t+1]=r>>>16,this[t+2]=r>>>8,this[t+3]=255&r):objectWriteUInt32(this,r,t,!1),t+4},Buffer.prototype.writeIntLE=function(r,t,e,n){if(r=+r,t|=0,!n){var o=Math.pow(2,8*e-1);checkInt(this,r,t,e,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&r;++i>0)-s&255;return t+e},Buffer.prototype.writeIntBE=function(r,t,e,n){if(r=+r,t|=0,!n){var o=Math.pow(2,8*e-1);checkInt(this,r,t,e,o-1,-o)}var i=e-1,a=1,s=0;for(this[t+i]=255&r;--i>=0&&(a*=256);)r<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(r/a>>0)-s&255;return t+e},Buffer.prototype.writeInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,127,-128),Buffer.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),r<0&&(r=255+r+1),this[t]=255&r,t+1},Buffer.prototype.writeInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer.prototype.writeInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer.prototype.writeInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,2147483647,-2147483648),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8,this[t+2]=r>>>16,this[t+3]=r>>>24):objectWriteUInt32(this,r,t,!0),t+4},Buffer.prototype.writeInt32BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,2147483647,-2147483648),r<0&&(r=4294967295+r+1),Buffer.TYPED_ARRAY_SUPPORT?(this[t]=r>>>24,this[t+1]=r>>>16,this[t+2]=r>>>8,this[t+3]=255&r):objectWriteUInt32(this,r,t,!1),t+4},Buffer.prototype.writeFloatLE=function(r,t,e){return writeFloat(this,r,t,!0,e)},Buffer.prototype.writeFloatBE=function(r,t,e){return writeFloat(this,r,t,!1,e)},Buffer.prototype.writeDoubleLE=function(r,t,e){return writeDouble(this,r,t,!0,e)},Buffer.prototype.writeDoubleBE=function(r,t,e){return writeDouble(this,r,t,!1,e)},Buffer.prototype.copy=function(r,t,e,n){if(e||(e=0),n||0===n||(n=this.length),t>=r.length&&(t=r.length),t||(t=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),r.length-t=0;--o)r[o+t]=this[o+e];else if(i<1e3||!Buffer.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,e=void 0===e?this.length:e>>>0,r||(r=0),"number"==typeof r)for(i=t;i55295&&e<57344){if(!o){if(e>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===n){(t-=3)>-1&&i.push(239,191,189);continue}o=e;continue}if(e<56320){(t-=3)>-1&&i.push(239,191,189),o=e;continue}e=65536+(o-55296<<10|e-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,e<128){if((t-=1)<0)break;i.push(e)}else if(e<2048){if((t-=2)<0)break;i.push(e>>6|192,63&e|128)}else if(e<65536){if((t-=3)<0)break;i.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return i}function asciiToBytes(r){for(var t=[],e=0;e>8,o=e%256,i.push(o),i.push(n);return i}function base64ToBytes(r){return toByteArray(base64clean(r))}function blitBuffer(r,t,e,n){for(var o=0;o=t.length||o>=r.length);++o)t[o+e]=r[o];return o}function isnan(r){return r!=r}function isBuffer(r){return null!=r&&(!!r._isBuffer||isFastBuffer(r)||isSlowBuffer(r))}function isFastBuffer(r){return!!r.constructor&&"function"==typeof r.constructor.isBuffer&&r.constructor.isBuffer(r)}function isSlowBuffer(r){return"function"==typeof r.readFloatLE&&"function"==typeof r.slice&&isFastBuffer(r.slice(0,0))}function buff(r,t){return void 0===t&&(t=BASE64_FORMAT),isBuffer(r)?r:new Buffer.from(r,t)}var replaceErrors=function(r,t){if(t instanceof Error){var e={};return Object.getOwnPropertyNames(t).forEach((function(r){e[r]=t[r]})),e}return t},printError=function(r){return JSON.stringify(r,replaceErrors)};function findFromContract(r,t,e){return!!(e[r]&&e[r][t]&&e[r][t].file&&fs.existsSync(e[r][t].file))&&e[r][t].file}var DOT=".",getDocLen=function(r){return Buffer.byteLength(r,"utf8")},headerParser=function(r,t){try{var e=r.headers.accept.split(",");return t?e.filter((function(r){return r===t})):e}catch(r){return[]}},isHeaderPresent=function(r,t){return!!headerParser(r,t).length},getPathToFn=function(r,t,e){var n=e.resolverDir,o=dasherize(r),i=[];e.contract&&e.contract[t]&&e.contract[t].path&&i.push(e.contract[t].path),i.push(path.join(n,t,o,[INDEX_KEY,EXT].join(DOT))),i.push(path.join(n,t,[o,EXT].join(DOT)));for(var a=i.length,s=0;s e instanceof err)\n .map(err => err.name)\n}\n\n/**\n * @param {array} errs list of errors to compare from\n * @param {object} e the error captured\n * @return {string} name of the error object\n */\nfunction getErrorNameByInstance(errs, e) {\n let error = mapErrToName(errs, e)\n return error.length ? error[0] : UNKNOWN_ERROR\n}\n\n/**\n * the same as above with a default JsonqlError as default\n * @param {array} errs same\n * @param {object} e error itself\n * @return {string} the name of the error\n */\nfunction getErrorNameByInstanceWithDefault(errs, e) {\n let name = getErrorNameByInstance(errs, e)\n return name === UNKNOWN_ERROR ? 'JsonqlError' : name;\n}\n\n\nexport {\n getErrorNameByInstanceWithDefault,\n getErrorNameByInstance,\n UNKNOWN_ERROR\n}\n","var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":["const"],"mappings":"6scAAAA,kvPCAA"} \ No newline at end of file diff --git a/packages/utils/es.js b/packages/utils/module.js similarity index 68% rename from packages/utils/es.js rename to packages/utils/module.js index 0a5ec7b1e17925c94973321b2b124361e6e8a6e4..2894a0a880aa45e6266a167607341a4d006651ad 100644 --- a/packages/utils/es.js +++ b/packages/utils/module.js @@ -1,17 +1,15 @@ // exportfor ES modules // ported from jsonql-params-validator import { chainFns, chainPromises } from './src/chain-fns' +import { injectToFn, objDefineProps } from './src/obj-define-props' import { checkIsContract, extractSocketPart, groupByNamespace, - findFromContract, extractArgsFromPayload, extractParamsFromContract } from './src/contract' -import { replaceErrors, printError } from './src/error' import { - getDebug, inArray, toArray, isKeyInObject, @@ -21,27 +19,9 @@ import { cacheBurst, cacheBurstUrl, dasherize, - getConfigValue + getConfigValue, + isNotEmpty } from './src/generic' -import { - isJsonqlPath, - isJsonqlRequest, - isJsonqlConsoleUrl, - handleOutput, - handleHtmlOutput, - ctxErrorHandler, - forbiddenHandler -} from './src/koa' -import { - getDocLen, - headerParser, - isHeaderPresent, - getCallMethod, - getPathToFn, - packResult, - packError, - resultHandler -} from './src/middleware' import { toPayload, formatPayload, @@ -55,28 +35,33 @@ import { getMutationFromPayload, getNameFromPayload } from './src/params-api' -import { buff } from './src/jwt' -import { injectToFn, objDefineProps } from './src/obj-define-props' +import { + getCallMethod, + packResult, + packError, + resultHandler +} from './src/results' + // alias const isContract = checkIsContract; +const VERSION = '__VERSION__' // exports export { + getCallMethod, + packResult, + packError, + resultHandler, // chain-fns chainFns, chainPromises, // contract - findFromContract, extractArgsFromPayload, extractParamsFromContract, checkIsContract, extractSocketPart, groupByNamespace, isContract, // alias - // error - replaceErrors, - printError, // generic - getDebug, inArray, isKeyInObject, dasherize, @@ -86,23 +71,7 @@ export { cacheBurst, cacheBurstUrl, getConfigValue, - // koa - isJsonqlPath, - isJsonqlRequest, - isJsonqlConsoleUrl, - handleOutput, - handleHtmlOutput, - ctxErrorHandler, - forbiddenHandler, - // middleware - getDocLen, - headerParser, - isHeaderPresent, - getCallMethod, - getPathToFn, - packResult, - packError, - resultHandler, + isNotEmpty, // params-api toPayload, formatPayload, @@ -115,9 +84,8 @@ export { getMutationFromArgs, getMutationFromPayload, getNameFromPayload, - // node - buff, // objectDefineProp injectToFn, - objDefineProps + objDefineProps, + VERSION } diff --git a/packages/utils/package.json b/packages/utils/package.json index 8c7385c17cb0642d17315a4b67e06eb450c86fbf..d9e12ee2f0388a0037e5c9cb87bc5fd5fd447662 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,17 +1,25 @@ { "name": "jsonql-utils", - "version": "0.4.9", + "version": "0.6.10", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", - "module": "es.js", + "module": "index.js", + "browser": "browser.js", "files": [ "main.js", - "es.js", + "index.js", + "module.js", + "browser.js", + "debug.js", "src" ], "scripts": { "test": "ava --verbose", - "prepare": "npm run test", + "prepare": "npm run build && npm run test", + "build:cjs": "rollup -c", + "build:umd": "NODE_ENV=BROWSER rollup -c", + "build:client": "NODE_ENV=CLIENT rollup -c", + "build": "npm run build:cjs && npm run build:umd", "test:define": "DEBUG=jsonql* ava --verbose ./tests/define-property.test.js", "test:params": "DEBUG=jsonql* ava ./tests/params-api.test.js" }, @@ -50,14 +58,28 @@ "compileEnhancements": false }, "dependencies": { - "debug": "^4.1.1", - "esm": "^3.2.25", - "jsonql-constants": "^1.8.2", - "jsonql-errors": "^1.1.2", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", "lodash-es": "^4.17.15" }, "devDependencies": { "ava": "^2.3.0", - "fs-extra": "^8.1.0" + "debug": "^4.1.1", + "esm": "^3.2.25", + "fs-extra": "^8.1.0", + "rollup": "^1.21.3", + "rollup-plugin-alias": "^2.0.0", + "rollup-plugin-analyzer": "^3.2.1", + "rollup-plugin-async": "^1.2.0", + "rollup-plugin-buble": "^0.19.8", + "rollup-plugin-bundle-size": "^1.0.3", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-node-builtins": "^2.1.2", + "rollup-plugin-node-globals": "^1.4.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-replace": "^2.2.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^5.1.2" } } diff --git a/packages/utils/rollup.config.js b/packages/utils/rollup.config.js new file mode 100644 index 0000000000000000000000000000000000000000..5f2f6147f1ac118d982b8b87170894fa9d8ca401 --- /dev/null +++ b/packages/utils/rollup.config.js @@ -0,0 +1,81 @@ +/** + * Rollup config for building the node.js version for jsonql-utils + */ +import { join } from 'path' +import buble from 'rollup-plugin-buble' +import { terser } from "rollup-plugin-terser" +import replace from 'rollup-plugin-replace' +import commonjs from 'rollup-plugin-commonjs' +import nodeResolve from 'rollup-plugin-node-resolve' +import nodeGlobals from 'rollup-plugin-node-globals' +// import builtins from 'rollup-plugin-node-builtins' +import size from 'rollup-plugin-bundle-size' +import async from 'rollup-plugin-async' + +import pkg from './package.json' + +const env = process.env.NODE_ENV; + +let plugins = [ + buble({ + objectAssign: 'Object.assign' + }), + nodeResolve({ + preferBuiltins: true + }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + // builtins(), + async(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + '__VERSION__': pkg.version + }) +] + +let globals = {} +let external = [ + 'debug', + 'fs', + 'path', + 'tty', + 'util', + 'os' +] + +let sourceFile = 'index.js' +let distFile = 'main.js' +let type = 'cjs' + +switch (env) { + case 'BROWSER': + sourceFile = 'module.js' + distFile = 'browser.js' + type = 'umd' + plugins.push(terser()) + break; + case 'CLIENT': + sourceFile = 'module.js' + distFile = join('..', '@jsonql', 'client', 'src', 'jsonql-utils.js') + type = 'es' + break; + default: + plugins.push(terser()) +} +plugins.push(size()) +let config = { + input: join(__dirname, sourceFile), + output: { + name: 'jsonqlUtils', + file: join(__dirname, distFile), + format: type, + sourcemap: env !== 'CLIENT', + globals + }, + plugins, + external +} + +export default config diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 593139a6f1dd0788cbba644122f65fa73bde5acc..5d3b22d0fa2e163c06e0a6449fc47221d01a079a 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -1,6 +1,6 @@ -// contract related methods -// This is ported back from ws-server and it will get use in the server / client side -import fs from 'fs' +// split the contract into the node side and the generic side +import { isKeyInObject } from './generic' +import { isPlainObject } from './lodash' import { QUERY_NAME, MUTATION_NAME, @@ -10,9 +10,6 @@ import { CONDITION_PARAM_NAME } from 'jsonql-constants' import { JsonqlError, JsonqlResolverNotFoundError } from 'jsonql-errors' -import { isKeyInObject } from './generic' -import { isPlainObject } from 'lodash-es' - /** * Check if the json is a contract file or not * @param {object} contract json object @@ -79,23 +76,6 @@ export function groupByNamespace(contract, fallback = false) { return { size, nspSet, publicNamespace } } -/** - * ported from jsonql-resolver - * Using the contract to find the function to call - * @param {string} type of resolver - * @param {string} name of resolver - * @param {object} contract to search from - * @return {string} file path to function - */ -export function findFromContract(type, name, contract) { - if (contract[type] && contract[type][name] && contract[type][name].file) { - if (fs.existsSync(contract[type][name].file)) { - return contract[type][name].file; - } - } - return false; -} - /** * Extract the args from the payload * @param {object} payload to work with diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 82e90417d2db7bce2c763797343891c417912eec..088be6e444e983ebec12c4528d99072f9099707a 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -1,14 +1,5 @@ // bunch of generic helpers -import debug from 'debug' -import { isArray, isPlainObject } from 'lodash-es' - -/** - * @param {string} name the name part after the : - * @param {string} baseName the base before the : - */ -export const getDebug = (name, baseName = 'jsonql') => { - return debug(baseName).extend(name) -} +import { isArray, isPlainObject, trim } from './lodash' /** * DIY in Array @@ -56,9 +47,7 @@ export const timestamp = (sec = false) => { export const urlParams = (url, params) => { let parts = []; for (let key in params) { - parts.push( - [key, params[key]].join('=') - ); + parts.push( [key, params[key]].join('=') ) } return [url, parts.join('&')].join('?') } @@ -82,8 +71,7 @@ export const cacheBurst = () => ({ _cb: timestamp() }) * @return {string} dasherize string */ export const dasherize = str => ( - (str+'') - .trim() + trim(str) .replace(/([A-Z])/g, '-$1') .replace(/[-_\s]+/g, '-') .toLowerCase() @@ -98,3 +86,12 @@ export const dasherize = str => ( export const getConfigValue = (name, obj) => ( obj && isPlainObject(obj) ? ( (name in obj) ? obj[name] : undefined ) : undefined ) + +/** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ +export const isNotEmpty = function(param) { + return param !== undefined && param !== false && param !== null && trim(param) !== ''; +} diff --git a/packages/utils/src/lodash.js b/packages/utils/src/lodash.js new file mode 100644 index 0000000000000000000000000000000000000000..275c7b87862c785cd648c722b0483e4fbb8c11d1 --- /dev/null +++ b/packages/utils/src/lodash.js @@ -0,0 +1,13 @@ +// first import all the required lodash module then re-export it +// that will reduce the change rollup get it wrong and ended up with the entire lodash +import isArray from 'lodash-es/isArray' +import isPlainObject from 'lodash-es/isPlainObject' +import trim from 'lodash-es/trim' +import isString from 'lodash-es/isString' + +export { + isArray, + isPlainObject, + isString, + trim +} diff --git a/packages/utils/src/error.js b/packages/utils/src/node-error.js similarity index 83% rename from packages/utils/src/error.js rename to packages/utils/src/node-error.js index 9679b340ce21e1f5b0fa4e8b1481051e51bd5892..fa4a00e5b98ce88d6a4d04efca4330904a2f1490 100644 --- a/packages/utils/src/error.js +++ b/packages/utils/src/node-error.js @@ -1,5 +1,5 @@ // some useful methods for error handling -import { inspect } from 'util' +// import { inspect } from 'util' /** * Port this from the CIS App * @param {string} key of object @@ -24,6 +24,6 @@ export const replaceErrors = function(key, value) { */ export const printError = function(error) { //return 'MASKED'; //error.toString(); - // return JSON.stringify(error, replaceErrors); - return inspect(error, false, null, true) + return JSON.stringify(error, replaceErrors) + // return inspect(error, false, null, true) } diff --git a/packages/utils/src/node-find-from-contract.js b/packages/utils/src/node-find-from-contract.js new file mode 100644 index 0000000000000000000000000000000000000000..643ef338178a9948c54b6e4d48b38ca1fd981603 --- /dev/null +++ b/packages/utils/src/node-find-from-contract.js @@ -0,0 +1,20 @@ +// contract related methods +// This is ported back from ws-server and it will get use in the server / client side +import fs from 'fs' + +/** + * ported from jsonql-resolver + * Using the contract to find the function to call + * @param {string} type of resolver + * @param {string} name of resolver + * @param {object} contract to search from + * @return {string} file path to function + */ +export function findFromContract(type, name, contract) { + if (contract[type] && contract[type][name] && contract[type][name].file) { + if (fs.existsSync(contract[type][name].file)) { + return contract[type][name].file; + } + } + return false; +} diff --git a/packages/utils/src/koa.js b/packages/utils/src/node-koa.js similarity index 91% rename from packages/utils/src/koa.js rename to packages/utils/src/node-koa.js index f4bd879577d8e69c41945dca82b946f7f4d08555..e757a80aef9856541a51666fdedfbb5c68b285dc 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/node-koa.js @@ -10,13 +10,15 @@ import { getDocLen, headerParser, isHeaderPresent, + getPathToFn +} from './node-middleware' +import { getCallMethod, - getPathToFn, packResult, packError -} from './middleware' -import { dasherize, getDebug } from './generic' -const debug = getDebug(`koa`, `jsonql-utils`) +} from './results' +import { dasherize } from './generic' + /** * @TODO need to be more flexible * @param {object} ctx koa @@ -88,16 +90,16 @@ export const handleHtmlOutput = function(ctx, body) { */ export const ctxErrorHandler = function(ctx, code, e, message = '') { const render = handleOutput({contentType: CONTENT_TYPE}) - debug('[ctxErrorHandler]', code, e, message) + // debug('[ctxErrorHandler]', code, e, message) let name; if (typeof code === 'string') { name = code; code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1; } else { - debug(`[ctxErrorHandler] using getErrorByStatus`) + // debug(`[ctxErrorHandler] using getErrorByStatus`) name = jsonqlErrors.getErrorByStatus(code) } - debug(`[ctxErrorHandler.name]`, name) + // debug(`[ctxErrorHandler.name]`, name) // preserve the message if (!message && e && e.message) { message = e.message; diff --git a/packages/utils/src/middleware.js b/packages/utils/src/node-middleware.js similarity index 61% rename from packages/utils/src/middleware.js rename to packages/utils/src/node-middleware.js index 5c7ee99e00e30dc0dfef99ddff3878253e99dc5b..9b53bad4ebae206315472211a793b8c4eeaf2327 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/node-middleware.js @@ -1,6 +1,7 @@ // this is a collection of middleware methods // should be good to use in Koa or Express // const { trim } = require('lodash-es') +import { join } from 'path' import fs from 'fs' import { QUERY_NAME, @@ -56,23 +57,6 @@ export const isHeaderPresent = (req, type) => { return !!headers.length; } -/** - * getting what is calling after the above check - * @param {string} method of call - * @return {mixed} false on failed - */ -export const getCallMethod = method => { - const [ POST, PUT ] = API_REQUEST_METHODS; - switch (true) { - case method === POST: - return QUERY_NAME; - case method === PUT: - return MUTATION_NAME; - default: - return false; - } -} - /** * @param {string} name of the resolver * @param {string} type what type of resolver @@ -96,36 +80,3 @@ export const getPathToFn = function(name, type, opts) { } return false; } - -/** - * wrapper method - * @param {mixed} result of fn return - * @return {string} stringify data - */ -export const packResult = function(result) { - return JSON.stringify({ [DATA_KEY]: result }) -} - -/** - * wrapper method - the output is trying to match up the structure of the Error sub class - * @param {mixed} detail of fn error - * @param {string} [className=JsonqlError] the errorName - * @param {number} [statusCode=500] the original error code - * @return {string} stringify error - */ -export const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { - return JSON.stringify({ - [ERROR_KEY]: { detail, className, statusCode, message } - }) -} - -// ported from http-client - -/** - * handle the return data - * @param {object} result return from server - * @return {object} strip the data part out, or if the error is presented - */ -export const resultHandler = result => ( - (isKeyInObject(result, DATA_KEY) && !isKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result -) diff --git a/packages/utils/src/params-api.js b/packages/utils/src/params-api.js index eba779b449a5e60a690d52cae6697ef9e0d6487b..8762a7f63299f80dc891931722e363ac59b7a0fe 100644 --- a/packages/utils/src/params-api.js +++ b/packages/utils/src/params-api.js @@ -14,7 +14,7 @@ import isString from './string' import { isArray } from './array' import { checkIsObject } from './object' */ -import { isString, isArray, isPlainObject } from 'lodash-es' +import { isString, isArray, isPlainObject } from './lodash' /** * make sure it's an object (it was call formatPayload but it doesn't make sense) diff --git a/packages/utils/src/results.js b/packages/utils/src/results.js new file mode 100644 index 0000000000000000000000000000000000000000..ee6f385c0df9111f83c035b9424b76e739fe1933 --- /dev/null +++ b/packages/utils/src/results.js @@ -0,0 +1,64 @@ +// break up from node-middleware +import { + QUERY_NAME, + MUTATION_NAME, + API_REQUEST_METHODS, + PAYLOAD_PARAM_NAME, + CONDITION_PARAM_NAME, + RESOLVER_PARAM_NAME , + QUERY_ARG_NAME, + DATA_KEY, + ERROR_KEY, + INDEX_KEY, + EXT +} from 'jsonql-constants' +import { isKeyInObject } from './generic' +/** + * getting what is calling after the above check + * @param {string} method of call + * @return {mixed} false on failed + */ +export const getCallMethod = method => { + const [ POST, PUT ] = API_REQUEST_METHODS; + switch (true) { + case method === POST: + return QUERY_NAME; + case method === PUT: + return MUTATION_NAME; + default: + return false; + } +} + +/** + * wrapper method + * @param {mixed} result of fn return + * @return {string} stringify data + */ +export const packResult = function(result) { + return JSON.stringify({ [DATA_KEY]: result }) +} + +/** + * wrapper method - the output is trying to match up the structure of the Error sub class + * @param {mixed} detail of fn error + * @param {string} [className=JsonqlError] the errorName + * @param {number} [statusCode=500] the original error code + * @return {string} stringify error + */ +export const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { + return JSON.stringify({ + [ERROR_KEY]: { detail, className, statusCode, message } + }) +} + +// ported from http-client + +/** + * handle the return data + * @param {object} result return from server + * @return {object} strip the data part out, or if the error is presented + */ +export const resultHandler = result => ( + (isKeyInObject(result, DATA_KEY) && !isKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result +) diff --git a/packages/utils/tests/client-utils.test.js b/packages/utils/tests/client-utils.test.js index 4119182389b16d5ea1420b170db841cdc36666e4..ea0760f98870c2544393b8be834000e939a25926 100644 --- a/packages/utils/tests/client-utils.test.js +++ b/packages/utils/tests/client-utils.test.js @@ -1,11 +1,17 @@ // testing the client utils methods const test = require('ava') -const { groupByNamespace, chainPromises } = require('../main') +const { groupByNamespace, chainPromises, VERSION } = require('../main') const { join } = require('path') const fsx = require('fs-extra') +const pkg = fsx.readJsonSync(join(__dirname, '..', 'package.json')) const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract.json')) +test(`It should have the version field`, t => { + t.is(VERSION, pkg.version) +}) + + test('It should able to give me two list from the contract', t => { const { size, nspSet, publicNamespace } = groupByNamespace(contract) diff --git a/packages/utils/tests/fixtures/resolvers/query/test-nn.js b/packages/utils/tests/fixtures/resolvers/query/test-nn.js new file mode 100644 index 0000000000000000000000000000000000000000..ea7b8d1c946691b68827a57acba4db5c35fd0fa5 --- /dev/null +++ b/packages/utils/tests/fixtures/resolvers/query/test-nn.js @@ -0,0 +1,5 @@ + + +module.exports = function testNn() { + return `just a test` +} diff --git a/packages/utils/tests/get-fn-by-path.test.js b/packages/utils/tests/get-fn-by-path.test.js new file mode 100644 index 0000000000000000000000000000000000000000..36fee2a501714f28ccef84e86a8fedd9bfc60326 --- /dev/null +++ b/packages/utils/tests/get-fn-by-path.test.js @@ -0,0 +1,12 @@ +const test = require('ava') +const { getPathToFn } = require('../main') +const { join } = require('path') + +test(`It should able to find the fn just by searching path`, t => { + const resolverDir = join(__dirname, 'fixtures', 'resolvers') + + const name = 'testNn' + + t.truthy( getPathToFn(name, 'query', { resolverDir }) ) + +}) diff --git a/packages/utils/tests/module-export.test.js b/packages/utils/tests/module-export.test.js new file mode 100644 index 0000000000000000000000000000000000000000..83eb0d92eb14392916aa1bc57b68c47f26313877 --- /dev/null +++ b/packages/utils/tests/module-export.test.js @@ -0,0 +1,15 @@ +// the import module keep complaining some of the module is not exported by the module.js ? +const test = require('ava') +const { urlParams, cacheBurstUrl } = require('../module') + +test(`It should able to create an url using the params`, t => { + + const url = urlParams('http://localhost', {key1: 1, key2: 2}) + + t.truthy(url.indexOf('?') > -1) + + const url1 = cacheBurstUrl(url) + + t.truthy(url1.indexOf('_cb') > -1) + +}) diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js b/packages/validator/dist/jsonql-params-validator.cjs.js index bcc289f24a332651b264b69d8dd55038a5a64d5f..9370a9f1e6c287d2d8b81ab87d166686ac512415 100644 --- a/packages/validator/dist/jsonql-params-validator.cjs.js +++ b/packages/validator/dist/jsonql-params-validator.cjs.js @@ -1,2 +1,2 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("debug");var global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;function getRawTag(e){var r=hasOwnProperty.call(e,symToStringTag),t=e[symToStringTag];try{var n=!(e[symToStringTag]=void 0)}catch(e){}var o=nativeObjectToString.call(e);return n&&(r?e[symToStringTag]=t:delete e[symToStringTag]),o}var objectProto$1=Object.prototype,nativeObjectToString$1=objectProto$1.toString;function objectToString(e){return nativeObjectToString$1.call(e)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag$1=Symbol?Symbol.toStringTag:void 0;function baseGetTag(e){return null==e?void 0===e?undefinedTag:nullTag:symToStringTag$1&&symToStringTag$1 in Object(e)?getRawTag(e):objectToString(e)}function isObjectLike(e){return null!=e&&"object"==typeof e}var symbolTag="[object Symbol]";function isSymbol(e){return"symbol"==typeof e||isObjectLike(e)&&baseGetTag(e)==symbolTag}function arrayMap(e,r){for(var t=-1,n=null==e?0:e.length,o=Array(n);++t=HOT_COUNT)return arguments[0]}else n=0;return t.apply(void 0,arguments)}}function constant(e){return function(){return e}}var defineProperty=function(){try{var e=getNative(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),baseSetToString=defineProperty?function(e,r){return defineProperty(e,"toString",{configurable:!0,enumerable:!1,value:constant(r),writable:!0})}:identity,setToString=shortOut(baseSetToString);function baseFindIndex(e,r,t,n){for(var o=e.length,a=t+(n?1:-1);n?a--:++a>>0,r>>>=0;for(var a=Array(o);++n",NO_STATUS_CODE=-1,ARGS_NOT_ARRAY_ERR="args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)",PARAMS_NOT_ARRAY_ERR="params is not an array! Did something gone wrong when you generate the contract.json?",EXCEPTION_CASE_ERR="Could not understand your arguments and parameter structure!",DEFAULT_TYPE$1=DEFAULT_TYPE,ARRAY_TYPE_LFT$1=ARRAY_TYPE_LFT,ARRAY_TYPE_RGT$1=ARRAY_TYPE_RGT,TYPE_KEY$1=TYPE_KEY,OPTIONAL_KEY$1=OPTIONAL_KEY,ENUM_KEY$1=ENUM_KEY,ARGS_KEY$1=ARGS_KEY,CHECKER_KEY$1=CHECKER_KEY,ALIAS_KEY$1=ALIAS_KEY,ARRAY_TYPE$1=ARRAY_TYPE,OBJECT_TYPE$1=OBJECT_TYPE,STRING_TYPE$1=STRING_TYPE,BOOLEAN_TYPE$1=BOOLEAN_TYPE,NUMBER_TYPE$1=NUMBER_TYPE,KEY_WORD$1=KEY_WORD,OR_SEPERATOR$1=OR_SEPERATOR,combineFn=function(e){switch(e){case NUMBER_TYPE$1:return checkIsNumber;case STRING_TYPE$1:return checkIsString;case BOOLEAN_TYPE$1:return checkIsBoolean;default:return checkIsAny}},checkIsArray=function(e,r){return void 0===r&&(r=""),!!isArray(e)&&(""===r||""===trim(r)||!(0t.filter(function(e){return!combineFn(e)(r)}).length)}).length:t.length>t.filter(function(e){return!checkIsArray(r,e)}).length},checkIsObject=function(r,e){if(void 0===e&&(e=null),isPlainObject(r)){if(!e)return!0;if(checkIsArray(e))return!e.filter(function(e){var t=r[e.name];return!(e.type.length>e.type.filter(function(e){var r;return!!isUndefined(t)||(!1!==(r=isArrayLike$1(e))?!arrayTypeHandler({arg:t},r):!combineFn(e)(t))}).length)}).length}return!1},objectTypeHandler=function(e){var r=e.arg,t=e.param,n=[r];return Array.isArray(t.keys)&&t.keys.length&&n.push(t.keys),checkIsObject.apply(null,n)},isBrowser=function(){try{if(window||document)return!0}catch(e){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(e){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).where=function(){return whereAmI()},e}(Error),JsonqlEnumError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(n,e),n}(Error),JsonqlTypeError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(n,e),n}(Error),JsonqlCheckerError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(n,e),n}(Error),JsonqlError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,Error.captureStackTrace&&Error.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return NO_STATUS_CODE},Object.defineProperties(n,e),n}(JsonqlBaseError);function log(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,e)}catch(e){}}var optionalHandler=function(r){var e=r.arg,t=r.param;return!!notEmpty(e)&&!(t.type.length>t.type.filter(function(e){return validateHandler(e,r)}).length)},validateHandler=function(e,r){var t;switch(!0){case e===OBJECT_TYPE$1:return!objectTypeHandler(r);case e===ARRAY_TYPE$1:return!checkIsArray(r.arg);case!1!==(t=isArrayLike$1(e)):return!arrayTypeHandler(r,t);default:return!combineFn(e)(r.arg)}},getOptionalValue=function(e,r){return isUndefined(e)?!0!==r.optional||isUndefined(r.defaultvalue)?null:r.defaultvalue:e},normalizeArgs=function(t,o){if(!checkIsArray(o))throw new JsonqlError(PARAMS_NOT_ARRAY_ERR);if(0===o.length)return[];if(!checkIsArray(t))throw new JsonqlError(ARGS_NOT_ARRAY_ERR);switch(!0){case t.length==o.length:return log(1),t.map(function(e,r){return{arg:e,index:r,param:o[r]}});case!0===o[0].variable:log(2);var n=o[0].type;return t.map(function(e,r){return{arg:e,index:r,param:o[r]||{type:n,name:"_"}}});case t.lengtho.length:log(4);var a=o.length,i=[DEFAULT_TYPE$1];return t.map(function(e,r){var t=a<=r||!!o[r].optional,n=o[r]||{type:i,name:"_"+r};return{arg:t?getOptionalValue(e,n):e,index:r,param:n,optional:t}});default:throw log(5),new JsonqlError(EXCEPTION_CASE_ERR,{args:t,params:o})}},processReturn=function(e){return e.map(function(e){return e.arg})},validateSync=function(e,r,t){var n;void 0===t&&(t=!1);var o=normalizeArgs(e,r),a=o.filter(function(r){return!0===r.optional||!0===r.param.optional?optionalHandler(r):!(r.param.type.length>r.param.type.filter(function(e){return validateHandler(e,r)}).length)});return t?((n={})[ERROR_KEY]=a,n[DATA_KEY]=processReturn(o),n):a},validateAsync=function(n,o,a){return void 0===a&&(a=!1),new Promise(function(e,r){var t=validateSync(n,o,a);return a?t[ERROR_KEY].length?r(t[ERROR_KEY]):e(t[DATA_KEY]):t.length?r(t):e([])})},inArray=function(e,r){return!!e.filter(function(e){return e===r}).length},isKeyInObject=function(e,r){var t=Object.keys(e);return inArray(t,r)},lookup=[],revLookup=[],Arr="undefined"!=typeof Uint8Array?Uint8Array:Array,inited=!1;function init(){inited=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,t=e.length;r>16&255,a[s++]=n>>8&255,a[s++]=255&n;return 2==o?(n=revLookup[e.charCodeAt(r)]<<2|revLookup[e.charCodeAt(r+1)]>>4,a[s++]=255&n):1==o&&(n=revLookup[e.charCodeAt(r)]<<10|revLookup[e.charCodeAt(r+1)]<<4|revLookup[e.charCodeAt(r+2)]>>2,a[s++]=n>>8&255,a[s++]=255&n),a}function tripletToBase64(e){return lookup[e>>18&63]+lookup[e>>12&63]+lookup[e>>6&63]+lookup[63&e]}function encodeChunk(e,r,t){for(var n,o=[],a=r;a>2],o+=lookup[r<<4&63],o+="=="):2==n&&(r=(e[t-2]<<8)+e[t-1],o+=lookup[r>>10],o+=lookup[r>>4&63],o+=lookup[r<<2&63],o+="="),a.push(o),a.join("")}function read(e,r,t,n,o){var a,i,s=8*o-n-1,u=(1<>1,c=-7,l=t?o-1:0,h=t?-1:1,p=e[r+l];for(l+=h,a=p&(1<<-c)-1,p>>=-c,c+=s;0>=-c,c+=n;0>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-1,g=n?1:-1,y=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(s=isNaN(r)?1:0,i=c):(i=Math.floor(Math.log(r)/Math.LN2),r*(u=Math.pow(2,-i))<1&&(i--,u*=2),2<=(r+=1<=i+l?h/u:h*Math.pow(2,1-l))*u&&(i++,u/=2),c<=i+l?(s=0,i=c):1<=i+l?(s=(r*u-1)*Math.pow(2,o),i+=l):(s=r*Math.pow(2,l-1)*Math.pow(2,o),i=0));8<=o;e[t+p]=255&s,p+=g,s/=256,o-=8);for(i=i<=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|e}function internalIsBuffer(e){return!(null==e||!e._isBuffer)}function byteLength(e,r){if(internalIsBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var t=e.length;if(0===t)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return t;case"utf8":case"utf-8":case void 0:return utf8ToBytes(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*t;case"hex":return t>>>1;case"base64":return base64ToBytes(e).length;default:if(n)return utf8ToBytes(e).length;r=(""+r).toLowerCase(),n=!0}}function slowToString(e,r,t){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===t||t>this.length)&&(t=this.length),t<=0)return"";if((t>>>=0)<=(r>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return hexSlice(this,r,t);case"utf8":case"utf-8":return utf8Slice(this,r,t);case"ascii":return asciiSlice(this,r,t);case"latin1":case"binary":return latin1Slice(this,r,t);case"base64":return base64Slice(this,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,r,t);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function swap(e,r,t){var n=e[r];e[r]=e[t],e[t]=n}function bidirectionalIndexOf(e,r,t,n,o){if(0===e.length)return-1;if("string"==typeof t?(n=t,t=0):2147483647=e.length){if(o)return-1;t=e.length-1}else if(t<0){if(!o)return-1;t=0}if("string"==typeof r&&(r=Buffer$2.from(r,n)),internalIsBuffer(r))return 0===r.length?-1:arrayIndexOf(e,r,t,n,o);if("number"==typeof r)return r&=255,Buffer$2.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,r,t):Uint8Array.prototype.lastIndexOf.call(e,r,t):arrayIndexOf(e,[r],t,n,o);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(e,r,t,n,o){var a,i=1,s=e.length,u=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||r.length<2)return-1;s/=i=2,u/=2,t/=2}function f(e,r){return 1===i?e[r]:e.readUInt16BE(r*i)}if(o){var c=-1;for(a=t;a>>10&1023|55296),c=56320|1023&c),n.push(c),o+=l}return decodeCodePointsArray(n)}Buffer$2.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer$2.poolSize=8192,Buffer$2._augment=function(e){return e.__proto__=Buffer$2.prototype,e},Buffer$2.from=function(e,r,t){return from(null,e,r,t)},Buffer$2.TYPED_ARRAY_SUPPORT&&(Buffer$2.prototype.__proto__=Uint8Array.prototype,Buffer$2.__proto__=Uint8Array),Buffer$2.alloc=function(e,r,t){return alloc(null,e,r,t)},Buffer$2.allocUnsafe=function(e){return allocUnsafe$1(null,e)},Buffer$2.allocUnsafeSlow=function(e){return allocUnsafe$1(null,e)},Buffer$2.isBuffer=isBuffer$1,Buffer$2.compare=function(e,r){if(!internalIsBuffer(e)||!internalIsBuffer(r))throw new TypeError("Arguments must be Buffers");if(e===r)return 0;for(var t=e.length,n=r.length,o=0,a=Math.min(t,n);or&&(e+=" ... ")),""},Buffer$2.prototype.compare=function(e,r,t,n,o){if(!internalIsBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===t&&(t=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),r<0||t>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(o<=n&&t<=r)return 0;if(o<=n)return-1;if(t<=r)return 1;if(this===e)return 0;for(var a=(o>>>=0)-(n>>>=0),i=(t>>>=0)-(r>>>=0),s=Math.min(a,i),u=this.slice(n,o),f=e.slice(r,t),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n=n||"utf8";for(var a=!1;;)switch(n){case"hex":return hexWrite(this,e,r,t);case"utf8":case"utf-8":return utf8Write(this,e,r,t);case"ascii":return asciiWrite(this,e,r,t);case"latin1":case"binary":return latin1Write(this,e,r,t);case"base64":return base64Write(this,e,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,e,r,t);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},Buffer$2.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(e){var r=e.length;if(r<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,e);for(var t="",n=0;ne.length)throw new RangeError("Index out of range")}function objectWriteUInt16(e,r,t,n){r<0&&(r=65535+r+1);for(var o=0,a=Math.min(e.length-t,2);o>>8*(n?o:1-o)}function objectWriteUInt32(e,r,t,n){r<0&&(r=4294967295+r+1);for(var o=0,a=Math.min(e.length-t,4);o>>8*(n?o:3-o)&255}function checkIEEE754(e,r,t,n,o,a){if(t+n>e.length)throw new RangeError("Index out of range");if(t<0)throw new RangeError("Index out of range")}function writeFloat(e,r,t,n,o){return o||checkIEEE754(e,r,t,4),write(e,r,t,n,23,4),t+4}function writeDouble(e,r,t,n,o){return o||checkIEEE754(e,r,t,8),write(e,r,t,n,52,8),t+8}Buffer$2.prototype.slice=function(e,r){var t,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeUInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeUInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r+3]=e>>>24,this[r+2]=e>>>16,this[r+1]=e>>>8,this[r]=255&e):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeUInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeIntLE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=0,i=1,s=0;for(this[r]=255&e;++a>0)-s&255;return r+t},Buffer$2.prototype.writeIntBE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=t-1,i=1,s=0;for(this[r+a]=255&e;0<=--a&&(i*=256);)e<0&&0===s&&0!==this[r+a+1]&&(s=1),this[r+a]=(e/i>>0)-s&255;return r+t},Buffer$2.prototype.writeInt8=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,1,127,-128),Buffer$2.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[r]=255&e,r+1},Buffer$2.prototype.writeInt16LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8,this[r+2]=e>>>16,this[r+3]=e>>>24):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeFloatLE=function(e,r,t){return writeFloat(this,e,r,!0,t)},Buffer$2.prototype.writeFloatBE=function(e,r,t){return writeFloat(this,e,r,!1,t)},Buffer$2.prototype.writeDoubleLE=function(e,r,t){return writeDouble(this,e,r,!0,t)},Buffer$2.prototype.writeDoubleBE=function(e,r,t){return writeDouble(this,e,r,!1,t)},Buffer$2.prototype.copy=function(e,r,t,n){if(t=t||0,n||0===n||(n=this.length),r>=e.length&&(r=e.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-r>>=0,t=void 0===t?this.length:t>>>0,"number"==typeof(e=e||0))for(a=r;a>6|192,63&t|128)}else if(t<65536){if((r-=3)<0)break;a.push(t>>12|224,t>>6&63|128,63&t|128)}else{if(!(t<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;a.push(t>>18|240,t>>12&63|128,t>>6&63|128,63&t|128)}}return a}function asciiToBytes(e){for(var r=[],t=0;t>8,o=t%256,a.push(o),a.push(n);return a}function base64ToBytes(e){return toByteArray(base64clean(e))}function blitBuffer(e,r,t,n){for(var o=0;o=r.length||o>=e.length);++o)r[o+t]=e[o];return o}function isnan(e){return e!=e}function isBuffer$1(e){return null!=e&&(!!e._isBuffer||isFastBuffer(e)||isSlowBuffer(e))}function isFastBuffer(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function isSlowBuffer(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&isFastBuffer(e.slice(0,0))}global$1.setTimeout,global$1.clearTimeout;var performance=global$1.performance||{},performanceNow=performance.now||performance.mozNow||performance.msNow||performance.oNow||performance.webkitNow||function(){return(new Date).getTime()},isEmpty=function(e){return!notEmpty(e)};function mapAliasConfigKeys(e,r){var t=omitBy(r,function(e,r){return!e[ALIAS_KEY$1]});return isEqual(t,{})?e:mapKeys(e,function(e,r){return findKey(t,function(e){return e.alias===r})||r})}function preservePristineValues(e,r){var t=mapAliasConfigKeys(e,r);return{pristineValues:mapValues(omitBy(r,function(e,r){return isKeyInObject(t,r)}),function(e){return e.args}),checkAgainstAppProps:omitBy(r,function(e,r){return!isKeyInObject(t,r)}),config:t}}function processConfigAction(o,e){return mapValues(e,function(e,r){var t,n;return isUndefined(o[r])||!0===e[OPTIONAL_KEY$1]&&isEmpty(o[r])?merge({},e,((t={})[KEY_WORD$1]=!0,t)):((n={})[ARGS_KEY$1]=o[r],n[TYPE_KEY$1]=e[TYPE_KEY$1],n[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1]||!1,n[ENUM_KEY$1]=e[ENUM_KEY$1]||!1,n[CHECKER_KEY$1]=e[CHECKER_KEY$1]||!1,n)})}function prepareArgsForValidation(e,r){var t=preservePristineValues(e,r),n=t.config,o=t.pristineValues;return[processConfigAction(n,t.checkAgainstAppProps),o]}var toArray=function(e){return checkIsArray(e)?e:[e]},inArray$1=function(e,r){return!!e.filter(function(e){return e===r}).length};function validateHandler$1(e,r){var t,n=[[e[ARGS_KEY$1]],[(t={},t[TYPE_KEY$1]=toArray(e[TYPE_KEY$1]),t[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1],t)]];return Reflect.apply(r,null,n)}var enumHandler=function(e,r){return!checkIsArray(r)||inArray$1(r,e)},checkerHandler=function(e,r){try{return!!isFunction(r)&&r.apply(null,[e])}catch(e){return!1}};function runValidationAction(n){return function(e,r){if(e[KEY_WORD$1])return e[ARGS_KEY$1];var t=validateHandler$1(e,n);if(t.length)throw log("runValidationAction",r,e),new JsonqlTypeError(r,t);if(!1!==e[ENUM_KEY$1]&&!enumHandler(e[ARGS_KEY$1],e[ENUM_KEY$1]))throw log(ENUM_KEY$1,e[ENUM_KEY$1]),new JsonqlEnumError(r);if(!1!==e[CHECKER_KEY$1]&&!checkerHandler(e[ARGS_KEY$1],e[CHECKER_KEY$1]))throw log(CHECKER_KEY$1,e[CHECKER_KEY$1]),new JsonqlCheckerError(r);return e[ARGS_KEY$1]}}function runValidation(e,r){var t=e[0],n=e[1],o=mapValues(t,runValidationAction(r));return merge(o,n)}var configToArgs=function(e,r){return Promise.resolve(prepareArgsForValidation(e,r))};function checkOptionsAsync(e,r,t,n){return void 0===e&&(e={}),configToArgs(e,r).then(function(e){return runValidation(e,n)}).then(function(e){return merge({},e,t)})}function checkOptionsSync(e,r,t,n){return void 0===e&&(e={}),merge(runValidation(prepareArgsForValidation(e,r),n),t)}function constructConfigFn(e,r,t,n,o,a){void 0===t&&(t=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===a&&(a=!1);var i={};return i[ARGS_KEY]=e,i[TYPE_KEY]=r,!0===t&&(i[OPTIONAL_KEY]=!0),checkIsArray(n)&&(i[ENUM_KEY]=n),isFunction(o)&&(i[CHECKER_KEY]=o),isString(a)&&(i[ALIAS_KEY]=a),i}var createConfig=function(e,r,t){void 0===t&&(t={});var n=t[OPTIONAL_KEY],o=t[ENUM_KEY],a=t[CHECKER_KEY],i=t[ALIAS_KEY];return constructConfigFn.apply(null,[e,r,n,o,a,i])},JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.8 module: cjs",checkConfigAsync=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsAsync(e,r,t,n)}},checkConfig=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsSync(e,r,t,n)}},isObject$1=checkIsObject,isAny=checkIsAny,isString$1=checkIsString,isBoolean$1=checkIsBoolean,isNumber$1=checkIsNumber,isArray$2=checkIsArray,isNotEmpty=notEmpty,normalizeArgs$1=normalizeArgs,validateSync$1=validateSync,validateAsync$1=validateAsync,JSONQL_PARAMS_VALIDATOR_INFO$1=JSONQL_PARAMS_VALIDATOR_INFO,createConfig$1=createConfig,constructConfig=constructConfigFn,checkConfigAsync$1=checkConfigAsync(validateSync),checkConfig$1=checkConfig(validateSync);exports.JSONQL_PARAMS_VALIDATOR_INFO=JSONQL_PARAMS_VALIDATOR_INFO$1,exports.checkConfig=checkConfig$1,exports.checkConfigAsync=checkConfigAsync$1,exports.constructConfig=constructConfig,exports.createConfig=createConfig$1,exports.isAny=isAny,exports.isArray=isArray$2,exports.isBoolean=isBoolean$1,exports.isNotEmpty=isNotEmpty,exports.isNumber=isNumber$1,exports.isObject=isObject$1,exports.isString=isString$1,exports.normalizeArgs=normalizeArgs$1,exports.validateAsync=validateAsync$1,exports.validateSync=validateSync$1; +"use strict";function isNull(e){return null===e}Object.defineProperty(exports,"__esModule",{value:!0});var global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol;function arrayMap(e,r){for(var t=-1,n=null==e?0:e.length,a=Array(n);++t>>0,r>>>=0;for(var o=Array(a);++n=HOT_COUNT)return arguments[0]}else n=0;return t.apply(void 0,arguments)}}var setToString=shortOut(baseSetToString);function baseRest(e,r){return setToString(overRest(e,r,identity),e+"")}function isIterateeCall(e,r,t){if(!isObject(t))return!1;var n=typeof r;return!!("number"==n?isArrayLike(t)&&isIndex(r,t.length):"string"==n&&r in t)&&eq(t[r],e)}function createAssigner(s){return baseRest(function(e,r){var t=-1,n=r.length,a=1",NO_STATUS_CODE=-1,ARGS_NOT_ARRAY_ERR="args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)",PARAMS_NOT_ARRAY_ERR="params is not an array! Did something gone wrong when you generate the contract.json?",EXCEPTION_CASE_ERR="Could not understand your arguments and parameter structure!",DEFAULT_TYPE$1=DEFAULT_TYPE,ARRAY_TYPE_LFT$1=ARRAY_TYPE_LFT,ARRAY_TYPE_RGT$1=ARRAY_TYPE_RGT,TYPE_KEY$1=TYPE_KEY,OPTIONAL_KEY$1=OPTIONAL_KEY,ENUM_KEY$1=ENUM_KEY,ARGS_KEY$1=ARGS_KEY,CHECKER_KEY$1=CHECKER_KEY,ALIAS_KEY$1=ALIAS_KEY,ARRAY_TYPE$1=ARRAY_TYPE,OBJECT_TYPE$1=OBJECT_TYPE,STRING_TYPE$1=STRING_TYPE,BOOLEAN_TYPE$1=BOOLEAN_TYPE,NUMBER_TYPE$1=NUMBER_TYPE,KEY_WORD$1=KEY_WORD,OR_SEPERATOR$1=OR_SEPERATOR,combineFn=function(e){switch(e){case NUMBER_TYPE$1:return checkIsNumber;case STRING_TYPE$1:return checkIsString;case BOOLEAN_TYPE$1:return checkIsBoolean;default:return checkIsAny}},checkIsArray=function(e,r){return void 0===r&&(r=""),!!isArray(e)&&(""===r||""===trim(r)||!(0t.filter(function(e){return!combineFn(e)(r)}).length)}).length:t.length>t.filter(function(e){return!checkIsArray(r,e)}).length},checkIsObject=function(r,e){if(void 0===e&&(e=null),isPlainObject(r)){if(!e)return!0;if(checkIsArray(e))return!e.filter(function(e){var t=r[e.name];return!(e.type.length>e.type.filter(function(e){var r;return!!isUndefined(t)||(!1!==(r=isArrayLike$1(e))?!arrayTypeHandler({arg:t},r):!combineFn(e)(t))}).length)}).length}return!1},objectTypeHandler=function(e){var r=e.arg,t=e.param,n=[r];return Array.isArray(t.keys)&&t.keys.length&&n.push(t.keys),checkIsObject.apply(null,n)},isBrowser=function(){try{if(window||document)return!0}catch(e){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(e){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).where=function(){return whereAmI()},e}(Error),JsonqlEnumError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(n,e),n}(Error),JsonqlTypeError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(n,e),n}(Error),JsonqlCheckerError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(n,e),n}(Error),JsonqlError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,Error.captureStackTrace&&Error.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return NO_STATUS_CODE},Object.defineProperties(n,e),n}(JsonqlBaseError);function log(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];try{window&&window.console&&Reflect.apply(console.log,console,e)}catch(e){}}var optionalHandler=function(r){var e=r.arg,t=r.param;return!!notEmpty(e)&&!(t.type.length>t.type.filter(function(e){return validateHandler(e,r)}).length)},validateHandler=function(e,r){var t;switch(!0){case e===OBJECT_TYPE$1:return!objectTypeHandler(r);case e===ARRAY_TYPE$1:return!checkIsArray(r.arg);case!1!==(t=isArrayLike$1(e)):return!arrayTypeHandler(r,t);default:return!combineFn(e)(r.arg)}},getOptionalValue=function(e,r){return isUndefined(e)?!0!==r.optional||isUndefined(r.defaultvalue)?null:r.defaultvalue:e},normalizeArgs=function(t,a){if(!checkIsArray(a))throw new JsonqlError(PARAMS_NOT_ARRAY_ERR);if(0===a.length)return[];if(!checkIsArray(t))throw new JsonqlError(ARGS_NOT_ARRAY_ERR);switch(!0){case t.length==a.length:return log(1),t.map(function(e,r){return{arg:e,index:r,param:a[r]}});case!0===a[0].variable:log(2);var n=a[0].type;return t.map(function(e,r){return{arg:e,index:r,param:a[r]||{type:n,name:"_"}}});case t.lengtha.length:log(4);var o=a.length,i=[DEFAULT_TYPE$1];return t.map(function(e,r){var t=o<=r||!!a[r].optional,n=a[r]||{type:i,name:"_"+r};return{arg:t?getOptionalValue(e,n):e,index:r,param:n,optional:t}});default:throw log(5),new JsonqlError(EXCEPTION_CASE_ERR,{args:t,params:a})}},processReturn=function(e){return e.map(function(e){return e.arg})},validateSync=function(e,r,t){var n;void 0===t&&(t=!1);var a=normalizeArgs(e,r),o=a.filter(function(r){return!0===r.optional||!0===r.param.optional?optionalHandler(r):!(r.param.type.length>r.param.type.filter(function(e){return validateHandler(e,r)}).length)});return t?((n={})[ERROR_KEY]=o,n[DATA_KEY]=processReturn(a),n):o},validateAsync=function(n,a,o){return void 0===o&&(o=!1),new Promise(function(e,r){var t=validateSync(n,a,o);return o?t[ERROR_KEY].length?r(t[ERROR_KEY]):e(t[DATA_KEY]):t.length?r(t):e([])})},isInArray=function(e,r){return!!e.filter(function(e){return e===r}).length},isKeyInObject=function(e,r){var t=Object.keys(e);return isInArray(t,r)},isEmpty=function(e){return!notEmpty(e)};function mapAliasConfigKeys(e,r){var t=omitBy(r,function(e,r){return!e[ALIAS_KEY$1]});return isEqual(t,{})?e:mapKeys(e,function(e,r){return findKey(t,function(e){return e.alias===r})||r})}function preservePristineValues(e,r){var t=mapAliasConfigKeys(e,r);return{pristineValues:mapValues(omitBy(r,function(e,r){return isKeyInObject(t,r)}),function(e){return e.args}),checkAgainstAppProps:omitBy(r,function(e,r){return!isKeyInObject(t,r)}),config:t}}function processConfigAction(a,e){return mapValues(e,function(e,r){var t,n;return isUndefined(a[r])||!0===e[OPTIONAL_KEY$1]&&isEmpty(a[r])?merge({},e,((t={})[KEY_WORD$1]=!0,t)):((n={})[ARGS_KEY$1]=a[r],n[TYPE_KEY$1]=e[TYPE_KEY$1],n[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1]||!1,n[ENUM_KEY$1]=e[ENUM_KEY$1]||!1,n[CHECKER_KEY$1]=e[CHECKER_KEY$1]||!1,n)})}function prepareArgsForValidation(e,r){var t=preservePristineValues(e,r),n=t.config,a=t.pristineValues;return[processConfigAction(n,t.checkAgainstAppProps),a]}var toArray=function(e){return checkIsArray(e)?e:[e]},inArray=function(e,r){return!!e.filter(function(e){return e===r}).length};function validateHandler$1(e,r){var t,n=[[e[ARGS_KEY$1]],[(t={},t[TYPE_KEY$1]=toArray(e[TYPE_KEY$1]),t[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1],t)]];return Reflect.apply(r,null,n)}var enumHandler=function(e,r){return!checkIsArray(r)||inArray(r,e)},checkerHandler=function(e,r){try{return!!isFunction(r)&&r.apply(null,[e])}catch(e){return!1}};function runValidationAction(n){return function(e,r){if(e[KEY_WORD$1])return e[ARGS_KEY$1];var t=validateHandler$1(e,n);if(t.length)throw log("runValidationAction",r,e),new JsonqlTypeError(r,t);if(!1!==e[ENUM_KEY$1]&&!enumHandler(e[ARGS_KEY$1],e[ENUM_KEY$1]))throw log(ENUM_KEY$1,e[ENUM_KEY$1]),new JsonqlEnumError(r);if(!1!==e[CHECKER_KEY$1]&&!checkerHandler(e[ARGS_KEY$1],e[CHECKER_KEY$1]))throw log(CHECKER_KEY$1,e[CHECKER_KEY$1]),new JsonqlCheckerError(r);return e[ARGS_KEY$1]}}function runValidation(e,r){var t=e[0],n=e[1],a=mapValues(t,runValidationAction(r));return merge(a,n)}var configToArgs=function(e,r){return Promise.resolve(prepareArgsForValidation(e,r))};function checkOptionsAsync(e,r,t,n){return void 0===e&&(e={}),configToArgs(e,r).then(function(e){return runValidation(e,n)}).then(function(e){return merge({},e,t)})}function checkOptionsSync(e,r,t,n){return void 0===e&&(e={}),merge(runValidation(prepareArgsForValidation(e,r),n),t)}function constructConfigFn(e,r,t,n,a,o){void 0===t&&(t=!1),void 0===n&&(n=!1),void 0===a&&(a=!1),void 0===o&&(o=!1);var i={};return i[ARGS_KEY]=e,i[TYPE_KEY]=r,!0===t&&(i[OPTIONAL_KEY]=!0),checkIsArray(n)&&(i[ENUM_KEY]=n),isFunction(a)&&(i[CHECKER_KEY]=a),isString(o)&&(i[ALIAS_KEY]=o),i}var createConfig=function(e,r,t){void 0===t&&(t={});var n=t[OPTIONAL_KEY],a=t[ENUM_KEY],o=t[CHECKER_KEY],i=t[ALIAS_KEY];return constructConfigFn.apply(null,[e,r,n,a,o,i])},JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.11 module: cjs",checkConfigAsync=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsAsync(e,r,t,n)}},checkConfig=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsSync(e,r,t,n)}},isObject$1=checkIsObject,isAny=checkIsAny,isString$1=checkIsString,isBoolean$1=checkIsBoolean,isNumber$1=checkIsNumber,isArray$1=checkIsArray,isNotEmpty=notEmpty,normalizeArgs$1=normalizeArgs,validateSync$1=validateSync,validateAsync$1=validateAsync,JSONQL_PARAMS_VALIDATOR_INFO$1=JSONQL_PARAMS_VALIDATOR_INFO,createConfig$1=createConfig,constructConfig=constructConfigFn,checkConfigAsync$1=checkConfigAsync(validateSync),checkConfig$1=checkConfig(validateSync),inArray$1=isInArray,isKeyInObject$1=isKeyInObject;exports.JSONQL_PARAMS_VALIDATOR_INFO=JSONQL_PARAMS_VALIDATOR_INFO$1,exports.checkConfig=checkConfig$1,exports.checkConfigAsync=checkConfigAsync$1,exports.constructConfig=constructConfig,exports.createConfig=createConfig$1,exports.inArray=inArray$1,exports.isAny=isAny,exports.isArray=isArray$1,exports.isBoolean=isBoolean$1,exports.isKeyInObject=isKeyInObject$1,exports.isNotEmpty=isNotEmpty,exports.isNumber=isNumber$1,exports.isObject=isObject$1,exports.isString=isString$1,exports.normalizeArgs=normalizeArgs$1,exports.validateAsync=validateAsync$1,exports.validateSync=validateSync$1; //# sourceMappingURL=jsonql-params-validator.cjs.js.map diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js.map b/packages/validator/dist/jsonql-params-validator.cjs.js.map index 29f1ab1ae8311b5c6881ba853b2e6308c5187321..8dad16878af3aedb6622ba7696e898036c775437 100644 --- a/packages/validator/dist/jsonql-params-validator.cjs.js.map +++ b/packages/validator/dist/jsonql-params-validator.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-params-validator.cjs.js","sources":["../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/buffer-es6/isArray.js"],"sourcesContent":["export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n","var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"qFAAA,2tvCCAA"} \ No newline at end of file +{"version":3,"file":"jsonql-params-validator.cjs.js","sources":["../node_modules/rollup-plugin-node-globals/src/global.js"],"sourcesContent":["export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n"],"names":[],"mappings":"uGAAA"} \ No newline at end of file diff --git a/packages/validator/dist/jsonql-params-validator.umd.js b/packages/validator/dist/jsonql-params-validator.umd.js index e26715d1a0acdda42b5b5cbf43e61b281635ec21..0a1f235fc859ea74ae93eef67e8f41a7851b535c 100644 --- a/packages/validator/dist/jsonql-params-validator.umd.js +++ b/packages/validator/dist/jsonql-params-validator.umd.js @@ -1,2 +1,2 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlParamsValidator={},t.debug)}(this,function(t,r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e="object"==typeof n&&n&&n.Object===Object&&n,o="object"==typeof self&&self&&self.Object===Object&&self,i=e||o||Function("return this")(),u=i.Symbol,a=Object.prototype,f=a.hasOwnProperty,c=a.toString,s=u?u.toStringTag:void 0;var h=Object.prototype.toString;var l="[object Null]",p="[object Undefined]",g=u?u.toStringTag:void 0;function v(t){return null==t?void 0===t?p:l:g&&g in Object(t)?function(t){var r=f.call(t,s),n=t[s];try{var e=!(t[s]=void 0)}catch(t){}var o=c.call(t);return e&&(r?t[s]=n:delete t[s]),o}(t):function(t){return h.call(t)}(t)}function y(t){return null!=t&&"object"==typeof t}var d="[object Symbol]";function b(t){return"symbol"==typeof t||y(t)&&v(t)==d}function w(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n>>0,r>>>=0;for(var i=Array(o);++e")){var r=t.replace(Ne,"").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1}function ke(t,n){var r=t.arg;return 1n.filter(function(t){return!Ue(t)(r)}).length)}).length:n.length>n.filter(function(t){return!Be(r,t)}).length}function Ye(r,t){if(void 0===t&&(t=null),Ar(r)){if(!t)return!0;if(Be(t))return!t.filter(function(t){var n=r[t.name];return!(t.type.length>t.type.filter(function(t){var r;return!!ve(n)||(!1!==(r=Ie(t))?!ke({arg:n},r):!Ue(t)(n))}).length)}).length}return!1}function Ce(){try{if(window||document)return!0}catch(t){}return!1}var xe="error",Me="optional",Le="enumv",ze="checker",De="alias",Ne="array.<",Fe="type",Ve=Me,$e=Le,qe="args",Je=ze,We=De,Ge="continue";function Qe(){return Ce()?"browser":function(){try{if(!Ce()&&n)return!0}catch(t){}return!1}()?"node":"unknown"}var Ze=function(n){function t(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t)}return n&&(t.__proto__=n),((t.prototype=Object.create(n&&n.prototype)).constructor=t).where=function(){return Qe()},t}(Error),He=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,t),e}(Error),Ke=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,t),e}(Error),Xe=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,t),e}(Error),to=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0},statusCode:{configurable:!0}};return t.name.get=function(){return"JsonqlError"},t.statusCode.get=function(){return-1},Object.defineProperties(e,t),e}(Ze);function ro(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}function no(t,r){return ve(t)?!0!==r.optional||ve(r.defaultvalue)?null:r.defaultvalue:t}function eo(n,o){if(!Be(o))throw new to("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===o.length)return[];if(!Be(n))throw new to("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case n.length==o.length:return ro(1),n.map(function(t,r){return{arg:t,index:r,param:o[r]}});case!0===o[0].variable:ro(2);var e=o[0].type;return n.map(function(t,r){return{arg:t,index:r,param:o[r]||{type:e,name:"_"}}});case n.lengtho.length:ro(4);var i=o.length,u=["any"];return n.map(function(t,r){var n=i<=r||!!o[r].optional,e=o[r]||{type:u,name:"_"+r};return{arg:n?no(t,e):t,index:r,param:e,optional:n}});default:throw ro(5),new to("Could not understand your arguments and parameter structure!",{args:n,params:o})}}function oo(t,r,n){var e;void 0===n&&(n=!1);var o=eo(t,r),i=o.filter(function(r){return!0===r.optional||!0===r.param.optional?function(r){var t=r.arg,n=r.param;return!!Oe(t)&&!(n.type.length>n.type.filter(function(t){return io(t,r)}).length)}(r):!(r.param.type.length>r.param.type.filter(function(t){return io(t,r)}).length)});return n?((e={})[xe]=i,e.data=function(t){return t.map(function(t){return t.arg})}(o),e):i}var io=function(t,r){var n;switch(!0){case"object"===t:return!function(t){var r=t.arg,n=t.param,e=[r];return Array.isArray(n.keys)&&n.keys.length&&e.push(n.keys),Ye.apply(null,e)}(r);case"array"===t:return!Be(r.arg);case!1!==(n=Ie(t)):return!ke(r,n);default:return!Ue(t)(r.arg)}},uo=function(t,r){return function(t,r){return!!t.filter(function(t){return t===r}).length}(Object.keys(t),r)},ao=[],fo=[],co="undefined"!=typeof Uint8Array?Uint8Array:Array,so=!1;function ho(){so=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,n=t.length;r>18&63]+ao[o>>12&63]+ao[o>>6&63]+ao[63&o]);return i.join("")}function po(t){var r;so||ho();for(var n=t.length,e=n%3,o="",i=[],u=0,a=n-e;u>2],o+=ao[r<<4&63],o+="=="):2==e&&(r=(t[n-2]<<8)+t[n-1],o+=ao[r>>10],o+=ao[r>>4&63],o+=ao[r<<2&63],o+="="),i.push(o),i.join("")}function go(t,r,n,e,o){var i,u,a=8*o-e-1,f=(1<>1,s=-7,h=n?o-1:0,l=n?-1:1,p=t[r+h];for(h+=l,i=p&(1<<-s)-1,p>>=-s,s+=a;0>=-s,s+=e;0>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=e?0:i-1,g=e?1:-1,v=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,u=s):(u=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-u))<1&&(u--,f*=2),2<=(r+=1<=u+h?l/f:l*Math.pow(2,1-h))*f&&(u++,f/=2),s<=u+h?(a=0,u=s):1<=u+h?(a=(r*f-1)*Math.pow(2,o),u+=h):(a=r*Math.pow(2,h-1)*Math.pow(2,o),u=0));8<=o;t[n+p]=255&a,p+=g,a/=256,o-=8);for(u=u<=wo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+wo().toString(16)+" bytes");return 0|t}function Ro(t){return!(null==t||!t._isBuffer)}function To(t,r){if(Ro(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var e=!1;;)switch(r){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Zo(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return Ho(t).length;default:if(e)return Zo(t).length;r=(""+r).toLowerCase(),e=!0}}function So(t,r,n){var e=t[r];t[r]=t[n],t[n]=e}function Uo(t,r,n,e,o){if(0===t.length)return-1;if("string"==typeof n?(e=n,n=0):2147483647=t.length){if(o)return-1;n=t.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof r&&(r=mo.from(r,e)),Ro(r))return 0===r.length?-1:Bo(t,r,n,e,o);if("number"==typeof r)return r&=255,mo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,n):Uint8Array.prototype.lastIndexOf.call(t,r,n):Bo(t,[r],n,e,o);throw new TypeError("val must be string, number or Buffer")}function Bo(t,r,n,e,o){var i,u=1,a=t.length,f=r.length;if(void 0!==e&&("ucs2"===(e=String(e).toLowerCase())||"ucs-2"===e||"utf16le"===e||"utf-16le"===e)){if(t.length<2||r.length<2)return-1;a/=u=2,f/=2,n/=2}function c(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(o){var s=-1;for(i=n;i>>10&1023|55296),s=56320|1023&s),e.push(s),o+=h}return function(t){var r=t.length;if(r<=xo)return String.fromCharCode.apply(String,t);var n="",e=0;for(;ethis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(r>>>=0))return"";for(t=t||"utf8";;)switch(t){case"hex":return zo(this,r,n);case"utf8":case"utf-8":return Co(this,r,n);case"ascii":return Mo(this,r,n);case"latin1":case"binary":return Lo(this,r,n);case"base64":return Yo(this,r,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Do(this,r,n);default:if(e)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),e=!0}}.apply(this,arguments)},mo.prototype.equals=function(t){if(!Ro(t))throw new TypeError("Argument must be a Buffer");return this===t||0===mo.compare(this,t)},mo.prototype.inspect=function(){var t="";return 0"},mo.prototype.compare=function(t,r,n,e,o){if(!Ro(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===n&&(n=t?t.length:0),void 0===e&&(e=0),void 0===o&&(o=this.length),r<0||n>t.length||e<0||o>this.length)throw new RangeError("out of range index");if(o<=e&&n<=r)return 0;if(o<=e)return-1;if(n<=r)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(e>>>=0),u=(n>>>=0)-(r>>>=0),a=Math.min(i,u),f=this.slice(e,o),c=t.slice(r,n),s=0;sthis.length)throw new RangeError("Attempt to write outside buffer bounds");e=e||"utf8";for(var i,u,a,f,c,s,h,l,p,g=!1;;)switch(e){case"hex":return Io(this,t,r,n);case"utf8":case"utf-8":return l=r,p=n,Ko(Zo(t,(h=this).length-l),h,l,p);case"ascii":return ko(this,t,r,n);case"latin1":case"binary":return ko(this,t,r,n);case"base64":return f=this,c=r,s=n,Ko(Ho(t),f,c,s);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return u=r,a=n,Ko(function(t,r){for(var n,e,o,i=[],u=0;u>8,o=n%256,i.push(o),i.push(e);return i}(t,(i=this).length-u),i,u,a);default:if(g)throw new TypeError("Unknown encoding: "+e);e=(""+e).toLowerCase(),g=!0}},mo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var xo=4096;function Mo(t,r,n){var e="";n=Math.min(t.length,n);for(var o=r;ot.length)throw new RangeError("Index out of range")}function Vo(t,r,n,e){r<0&&(r=65535+r+1);for(var o=0,i=Math.min(t.length-n,2);o>>8*(e?o:1-o)}function $o(t,r,n,e){r<0&&(r=4294967295+r+1);for(var o=0,i=Math.min(t.length-n,4);o>>8*(e?o:3-o)&255}function qo(t,r,n,e){if(n+e>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function Jo(t,r,n,e,o){return o||qo(t,0,n,4),vo(t,r,n,e,23,4),n+4}function Wo(t,r,n,e,o){return o||qo(t,0,n,8),vo(t,r,n,e,52,8),n+8}mo.prototype.slice=function(t,r){var n,e=this.length;if((t=~~t)<0?(t+=e)<0&&(t=0):e>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeUInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,65535,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeUInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):$o(this,t,r,!0),r+4},mo.prototype.writeUInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeIntLE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=0,u=1,a=0;for(this[r]=255&t;++i>0)-a&255;return r+n},mo.prototype.writeIntBE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=n-1,u=1,a=0;for(this[r+i]=255&t;0<=--i&&(u*=256);)t<0&&0===a&&0!==this[r+i+1]&&(a=1),this[r+i]=(t/u>>0)-a&255;return r+n},mo.prototype.writeInt8=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,1,127,-128),mo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},mo.prototype.writeInt16LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):$o(this,t,r,!0),r+4},mo.prototype.writeInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeFloatLE=function(t,r,n){return Jo(this,t,r,!0,n)},mo.prototype.writeFloatBE=function(t,r,n){return Jo(this,t,r,!1,n)},mo.prototype.writeDoubleLE=function(t,r,n){return Wo(this,t,r,!0,n)},mo.prototype.writeDoubleBE=function(t,r,n){return Wo(this,t,r,!1,n)},mo.prototype.copy=function(t,r,n,e){if(n=n||0,e||0===e||(e=this.length),r>=t.length&&(r=t.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(e<0)throw new RangeError("sourceEnd out of bounds");e>this.length&&(e=this.length),t.length-r>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(t=t||0))for(i=r;i>6|192,63&n|128)}else if(n<65536){if((r-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function Ho(t){return function(t){var r,n,e,o,i;so||ho();var u=t.length;if(0>16&255,i[a++]=e>>8&255,i[a++]=255&e;return 2==o?(e=fo[t.charCodeAt(r)]<<2|fo[t.charCodeAt(r+1)]>>4,i[a++]=255&e):1==o&&(e=fo[t.charCodeAt(r)]<<10|fo[t.charCodeAt(r+1)]<<4|fo[t.charCodeAt(r+2)]>>2,i[a++]=e>>8&255,i[a++]=255&e),i}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(Go,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Ko(t,r,n,e){for(var o=0;o=r.length||o>=t.length);++o)r[o+n]=t[o];return o}function Xo(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}n.setTimeout,n.clearTimeout;var ti=n.performance||{},ri=(ti.now||ti.mozNow||ti.msNow||ti.oNow||ti.webkitNow,function(t){return!Oe(t)});function ni(t,r){var n=Ae(r,function(t,r){return!t[We]});return function(t,r){return $n(t,r)}(n,{})?t:function(t,e){var o={};return e=ne(e),ie(t,function(t,r,n){ut(o,e(t,r,n),t)}),o}(t,function(t,r){return function(t,r){return function(t,e,r){var o;return r(t,function(t,r,n){if(e(t,r,n))return o=r,!1}),o}(t,ne(r),ie)}(n,function(t){return t.alias===r})||r})}function ei(t,r){var n=function(t,r){var n=ni(t,r);return{pristineValues:ye(Ae(r,function(t,r){return uo(n,r)}),function(t){return t.args}),checkAgainstAppProps:Ae(r,function(t,r){return!uo(n,r)}),config:n}}(t,r),e=n.config,o=n.pristineValues;return[function(o,t){return ye(t,function(t,r){var n,e;return ve(o[r])||!0===t[Ve]&&ri(o[r])?be({},t,((n={})[Ge]=!0,n)):((e={})[qe]=o[r],e[Fe]=t[Fe],e[Ve]=t[Ve]||!1,e[$e]=t[$e]||!1,e[Je]=t[Je]||!1,e)})}(e,n.checkAgainstAppProps),o]}var oi=function(t){return Be(t)?t:[t]};var ii=function(t,r){return!Be(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},ui=function(t,r){try{return!!B(r)&&r.apply(null,[t])}catch(t){return!1}};function ai(e){return function(t,r){if(t[Ge])return t[qe];var n=function(t,r){var n,e=[[t[qe]],[(n={},n[Fe]=oi(t[Fe]),n[Ve]=t[Ve],n)]];return Reflect.apply(r,null,e)}(t,e);if(n.length)throw ro("runValidationAction",r,t),new Ke(r,n);if(!1!==t[$e]&&!ii(t[qe],t[$e]))throw ro($e,t[$e]),new He(r);if(!1!==t[Je]&&!ui(t[qe],t[Je]))throw ro(Je,t[Je]),new Xe(r);return t[qe]}}function fi(t,r){var n=t[0],e=t[1],o=ye(n,ai(r));return be(o,e)}function ci(t,r,n,e){return void 0===t&&(t={}),function(t,r){return Promise.resolve(ei(t,r))}(t,r).then(function(t){return fi(t,e)}).then(function(t){return be({},t,n)})}function si(t,r,n,e,o,i){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===i&&(i=!1);var u={};return u.args=t,u.type=r,!0===n&&(u[Me]=!0),Be(e)&&(u[Le]=e),B(o)&&(u[ze]=o),le(i)&&(u[De]=i),u}function hi(e,o,i){return void 0===i&&(i=!1),new Promise(function(t,r){var n=oo(e,o,i);return i?n[xe].length?r(n[xe]):t(n.data):n.length?r(n):t([])})}function li(t,r,n){void 0===n&&(n={});var e=n[Me],o=n[Le],i=n[ze],u=n[De];return si.apply(null,[t,r,e,o,i,u])}var pi,gi,vi=Ye,yi=Se,di=Re,bi=Te,wi=Pe,_i=Be,mi=Oe,Ai=eo,ji=oo,Ei=si,Oi=(pi=oo,function(t,r,n){return void 0===n&&(n={}),ci(t,r,n,pi)}),Pi=(gi=oo,function(t,r,n){return void 0===n&&(n={}),function(t,r,n,e){return void 0===t&&(t={}),be(fi(ei(t,r),e),n)}(t,r,n,gi)});t.JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.8 module: umd",t.checkConfig=Pi,t.checkConfigAsync=Oi,t.constructConfig=Ei,t.createConfig=li,t.isAny=yi,t.isArray=_i,t.isBoolean=bi,t.isNotEmpty=mi,t.isNumber=wi,t.isObject=vi,t.isString=di,t.normalizeArgs=Ai,t.validateAsync=hi,t.validateSync=ji,Object.defineProperty(t,"__esModule",{value:!0})}); +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlParamsValidator={})}(this,function(t){"use strict";var r="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n="object"==typeof r&&r&&r.Object===Object&&r,e="object"==typeof self&&self&&self.Object===Object&&self,o=n||e||Function("return this")(),u=o.Symbol;function i(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n>>0,r>>>=0;for(var u=Array(o);++e")){var r=t.replace(Ve,"").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1}function Fe(t,n){var r=t.arg;return 1n.filter(function(t){return!xe(t)(r)}).length)}).length:n.length>n.filter(function(t){return!Te(r,t)}).length}function Ne(r,t){if(void 0===t&&(t=null),et(r)){if(!t)return!0;if(Te(t))return!t.filter(function(t){var n=r[t.name];return!(t.type.length>t.type.filter(function(t){var r;return!!U(n)||(!1!==(r=Ce(t))?!Fe({arg:n},r):!xe(t)(n))}).length)}).length}return!1}function $e(){try{if(window||document)return!0}catch(t){}return!1}var Be="error",Me="optional",Re="enumv",De="checker",Ie="alias",Ve="array.<",Le="type",qe=Me,Ue=Re,Je="args",We=De,Ge=Ie,Ke="continue";function Qe(){return $e()?"browser":function(){try{if(!$e()&&r)return!0}catch(t){}return!1}()?"node":"unknown"}var Ye=function(n){function t(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t)}return n&&(t.__proto__=n),((t.prototype=Object.create(n&&n.prototype)).constructor=t).where=function(){return Qe()},t}(Error),He=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,t),e}(Error),Xe=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,t),e}(Error),Ze=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,t),e}(Error),to=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0},statusCode:{configurable:!0}};return t.name.get=function(){return"JsonqlError"},t.statusCode.get=function(){return-1},Object.defineProperties(e,t),e}(Ye);function ro(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.console&&Reflect.apply(console.log,console,t)}catch(t){}}function no(t,r){return U(t)?!0!==r.optional||U(r.defaultvalue)?null:r.defaultvalue:t}function eo(n,o){if(!Te(o))throw new to("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===o.length)return[];if(!Te(n))throw new to("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case n.length==o.length:return ro(1),n.map(function(t,r){return{arg:t,index:r,param:o[r]}});case!0===o[0].variable:ro(2);var e=o[0].type;return n.map(function(t,r){return{arg:t,index:r,param:o[r]||{type:e,name:"_"}}});case n.lengtho.length:ro(4);var u=o.length,i=["any"];return n.map(function(t,r){var n=u<=r||!!o[r].optional,e=o[r]||{type:i,name:"_"+r};return{arg:n?no(t,e):t,index:r,param:e,optional:n}});default:throw ro(5),new to("Could not understand your arguments and parameter structure!",{args:n,params:o})}}function oo(t,r,n){var e;void 0===n&&(n=!1);var o=eo(t,r),u=o.filter(function(r){return!0===r.optional||!0===r.param.optional?function(r){var t=r.arg,n=r.param;return!!Se(t)&&!(n.type.length>n.type.filter(function(t){return io(t,r)}).length)}(r):!(r.param.type.length>r.param.type.filter(function(t){return io(t,r)}).length)});return n?((e={})[Be]=u,e.data=function(t){return t.map(function(t){return t.arg})}(o),e):u}function uo(t,r){return!!t.filter(function(t){return t===r}).length}var io=function(t,r){var n;switch(!0){case"object"===t:return!function(t){var r=t.arg,n=t.param,e=[r];return Array.isArray(n.keys)&&n.keys.length&&e.push(n.keys),Ne.apply(null,e)}(r);case"array"===t:return!Te(r.arg);case!1!==(n=Ce(t)):return!Fe(r,n);default:return!xe(t)(r.arg)}},ao=function(t,r){var n=Object.keys(t);return uo(n,r)},co=function(t){return!Se(t)};function fo(t,r){var n=Ae(r,function(t,r){return!t[Ge]});return function(t,r){return yn(t,r)}(n,{})?t:function(t,e){var o={};return e=Ln(e),Lt(t,function(t,r,n){Un(o,e(t,r,n),t)}),o}(t,function(t,r){return function(t,r){return function(t,e,r){var o;return r(t,function(t,r,n){if(e(t,r,n))return o=r,!1}),o}(t,Ln(r),Lt)}(n,function(t){return t.alias===r})||r})}function lo(t,r){var n=function(t,r){var n=fo(t,r);return{pristineValues:_e(Ae(r,function(t,r){return ao(n,r)}),function(t){return t.args}),checkAgainstAppProps:Ae(r,function(t,r){return!ao(n,r)}),config:n}}(t,r),e=n.config,o=n.pristineValues;return[function(o,t){return _e(t,function(t,r){var n,e;return U(o[r])||!0===t[qe]&&co(o[r])?be({},t,((n={})[Ke]=!0,n)):((e={})[Je]=o[r],e[Le]=t[Le],e[qe]=t[qe]||!1,e[Ue]=t[Ue]||!1,e[We]=t[We]||!1,e)})}(e,n.checkAgainstAppProps),o]}var so=function(t){return Te(t)?t:[t]};var po=function(t,r){return!Te(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},vo=function(t,r){try{return!!Dt(r)&&r.apply(null,[t])}catch(t){return!1}};function ho(e){return function(t,r){if(t[Ke])return t[Je];var n=function(t,r){var n,e=[[t[Je]],[(n={},n[Le]=so(t[Le]),n[qe]=t[qe],n)]];return Reflect.apply(r,null,e)}(t,e);if(n.length)throw ro("runValidationAction",r,t),new Xe(r,n);if(!1!==t[Ue]&&!po(t[Je],t[Ue]))throw ro(Ue,t[Ue]),new He(r);if(!1!==t[We]&&!vo(t[Je],t[We]))throw ro(We,t[We]),new Ze(r);return t[Je]}}function yo(t,r){var n=t[0],e=t[1],o=_e(n,ho(r));return be(o,e)}function go(t,r,n,e){return void 0===t&&(t={}),function(t,r){return Promise.resolve(lo(t,r))}(t,r).then(function(t){return yo(t,e)}).then(function(t){return be({},t,n)})}function bo(t,r,n,e,o,u){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===u&&(u=!1);var i={};return i.args=t,i.type=r,!0===n&&(i[Me]=!0),Te(e)&&(i[Re]=e),Dt(o)&&(i[De]=o),K(u)&&(i[Ie]=u),i}function _o(e,o,u){return void 0===u&&(u=!1),new Promise(function(t,r){var n=oo(e,o,u);return u?n[Be].length?r(n[Be]):t(n.data):n.length?r(n):t([])})}function jo(t,r,n){void 0===n&&(n={});var e=n[Me],o=n[Re],u=n[De],i=n[Ie];return bo.apply(null,[t,r,e,o,u,i])}var mo,wo,Oo=Ne,Ao=ze,So=ke,Po=Ee,ko=Pe,Eo=Te,zo=Se,xo=eo,To=oo,Co=bo,Fo=(mo=oo,function(t,r,n){return void 0===n&&(n={}),go(t,r,n,mo)}),No=(wo=oo,function(t,r,n){return void 0===n&&(n={}),function(t,r,n,e){return void 0===t&&(t={}),be(yo(lo(t,r),e),n)}(t,r,n,wo)}),$o=uo,Bo=ao;t.JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.11 module: umd",t.checkConfig=No,t.checkConfigAsync=Fo,t.constructConfig=Co,t.createConfig=jo,t.inArray=$o,t.isAny=Ao,t.isArray=Eo,t.isBoolean=Po,t.isKeyInObject=Bo,t.isNotEmpty=zo,t.isNumber=ko,t.isObject=Oo,t.isString=So,t.normalizeArgs=xo,t.validateAsync=_o,t.validateSync=To,Object.defineProperty(t,"__esModule",{value:!0})}); //# sourceMappingURL=jsonql-params-validator.umd.js.map diff --git a/packages/validator/dist/jsonql-params-validator.umd.js.map b/packages/validator/dist/jsonql-params-validator.umd.js.map index 07b453b652b5939c9781b3bbc36c941a0f70872e..ce1a9495eea1752ad38ca8f704a5d90dc46dc00b 100644 --- a/packages/validator/dist/jsonql-params-validator.umd.js.map +++ b/packages/validator/dist/jsonql-params-validator.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-params-validator.umd.js","sources":["../node_modules/buffer-es6/isArray.js"],"sourcesContent":["var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"sn2BAAA"} \ No newline at end of file +{"version":3,"file":"jsonql-params-validator.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/validator/index.js b/packages/validator/index.js index b398edf1c1669e913d9cdec981f2efe23952aec9..e144ab026e68efd4954b3b634f9bcf0685fc74b0 100644 --- a/packages/validator/index.js +++ b/packages/validator/index.js @@ -34,3 +34,10 @@ export const constructConfig = jsonqlOptions.constructConfigFn; export const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync) export const checkConfig = jsonqlOptions.checkConfig(validator.validateSync) + +// export the two extra functions +import isInArray from './src/is-in-array' +import isKeyInObjectFn from './src/is-key-in-object' + +export const inArray = isInArray; +export const isKeyInObject = isKeyInObjectFn; diff --git a/packages/validator/package.json b/packages/validator/package.json index e13561c364242f41cba0a29be5f23ef1d1e8753c..3b128d67e186e46c226cdb4e71135ffebe21d972 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-params-validator", - "version": "1.4.8", + "version": "1.4.11", "description": "JSONQL parameters validator written in ES6+ to use with the client / server", "module": "index.js", "browser": "dist/jsonql-params-validator.umd.js", @@ -8,8 +8,7 @@ "files": [ "dist", "src", - "index.js", - "main.js" + "index.js" ], "scripts": { "prepare": "npm run build", @@ -38,17 +37,16 @@ "jsonql" ], "dependencies": { - "jsonql-constants": "^1.8.2", - "jsonql-errors": "^1.1.2", - "jsonql-utils": "^0.4.6", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", "lodash-es": "^4.17.15" }, "devDependencies": { - "ava": "^2.3.0", + "ava": "^2.4.0", "debug": "^4.1.1", "esm": "^3.2.25", "fs-extra": "^8.1.0", - "rollup": "^1.20.3", + "rollup": "^1.21.4", "rollup-plugin-alias": "^2.0.0", "rollup-plugin-async": "^1.2.0", "rollup-plugin-buble": "^0.19.8", diff --git a/packages/validator/rollup.config.js b/packages/validator/rollup.config.js index 34e3df322928c4dc5788385daa8cb6be7e401732..d83c44e823f7b0479732f0cff389cb6b2b54e759 100644 --- a/packages/validator/rollup.config.js +++ b/packages/validator/rollup.config.js @@ -30,7 +30,7 @@ let plugins = [ }), nodeResolve({ preferBuiltins: true, - mainFields: ['module', 'main', 'browser'] + mainFields: ['module', 'browser'] }), commonjs({ include: 'node_modules/**' @@ -59,15 +59,12 @@ let config = { sourcemap: true, globals: { 'promise-polyfill': 'Promise', - 'debug': 'debug', - 'fs': 'fs', - 'util': 'util' + 'debug': 'debug' } }, external: [ - 'debug', - 'Promise', - 'promise-polyfill' + 'promise-polyfill', + 'debug' ], plugins: plugins }; diff --git a/packages/validator/src/any.js b/packages/validator/src/any.js index ea6dba5ae84ca3baad46b32b7452ce00b98c3775..71f96b818f54e427209961650c87bf2a4b1bc872 100644 --- a/packages/validator/src/any.js +++ b/packages/validator/src/any.js @@ -1,5 +1,6 @@ // validate any thing only check if there is something -import { isNull, trim, isUndefined } from 'lodash-es' + +import { isNull, trim, isUndefined } from './lodash' /** * @param {*} value the value * @param {boolean} [checkNull=true] strict check if there is null value diff --git a/packages/validator/src/array.js b/packages/validator/src/array.js index f85eff5edeeb7938309e16b1156503dfc672f08d..3523b15eed8c8faf4e33cbb43d9d0a3b2ecdda19 100644 --- a/packages/validator/src/array.js +++ b/packages/validator/src/array.js @@ -1,5 +1,5 @@ // validate array type -import { isArray, trim } from 'lodash-es' +import { isArray, trim } from './lodash' import combineFn from './combine' import { ARRAY_TYPE_LFT, diff --git a/packages/validator/src/boolean.js b/packages/validator/src/boolean.js index 1a11b1800ac7232fa3d7d99aa0184cbfac55c658..e73b2a107e870aaebf34e4019c1fec23e5eb0de7 100644 --- a/packages/validator/src/boolean.js +++ b/packages/validator/src/boolean.js @@ -1,5 +1,5 @@ // check for boolean -import { isBoolean } from 'lodash-es' +import { isBoolean } from './lodash' /** * @param {boolean} value expected * @return {boolean} true if OK diff --git a/packages/validator/src/is-key-in-object.js b/packages/validator/src/is-key-in-object.js new file mode 100644 index 0000000000000000000000000000000000000000..097c97e903b7ccc2fb2eadaa7421074ea393de7c --- /dev/null +++ b/packages/validator/src/is-key-in-object.js @@ -0,0 +1,9 @@ + +import isInArray from './is-in-array' + +const isKeyInObject = function(obj, key) { + const keys = Object.keys(obj) + return isInArray(keys, key) +} + +export default isKeyInObject; diff --git a/packages/validator/src/lodash.js b/packages/validator/src/lodash.js new file mode 100644 index 0000000000000000000000000000000000000000..e409301636974c8e3aeeb19758e38899952fa23e --- /dev/null +++ b/packages/validator/src/lodash.js @@ -0,0 +1,36 @@ +// group all the lodash import in one place +import isNull from 'lodash-es/isNull' +import trim from 'lodash-es/trim' +import isUndefined from 'lodash-es/isUndefined' +import isArray from 'lodash-es/isArray' +import isBoolean from 'lodash-es/isBoolean' +import isNaN from 'lodash-es/isNaN' +import isString from 'lodash-es/isString' +import isPlainObject from 'lodash-es/isPlainObject' +import filter from 'lodash-es/filter' +import merge from 'lodash-es/merge' +import isFunction from 'lodash-es/isFunction' +import mapValues from 'lodash-es/mapValues' +import mapKeys from 'lodash-es/mapKeys' +import omitBy from 'lodash-es/omitBy' +import isEqual from 'lodash-es/isEqual' +import findKey from 'lodash-es/findKey' + +export { + isNull, + trim, + isUndefined, + isArray, + isBoolean, + isNaN, + isString, + isPlainObject, + filter, + merge, + isFunction, + mapValues, + mapKeys, + omitBy, + isEqual, + findKey +} diff --git a/packages/validator/src/log.js b/packages/validator/src/log.js index 4fc773ca9f17303f751fc3900bff15e0ce3924d7..68d3a3ebd53bff8556472d814aec8dbb6ecef1bf 100644 --- a/packages/validator/src/log.js +++ b/packages/validator/src/log.js @@ -5,7 +5,7 @@ */ export default function log(...args) { try { - if (window && window.debug) { + if (window && window.console) { Reflect.apply(console.log, console, args) } } catch(e) {} diff --git a/packages/validator/src/not-empty.js b/packages/validator/src/not-empty.js index 9d1fdb66d64d7e1a671096856f86dc11d772c08c..02ce180d8368ce5b73659d2a4e09dbd28e0a3605 100644 --- a/packages/validator/src/not-empty.js +++ b/packages/validator/src/not-empty.js @@ -3,7 +3,7 @@ * @param {*} param input * @return {boolean} */ -import { trim, isArray } from 'lodash-es' +import { trim, isArray } from './lodash' export default a => { if (isArray(a)) { diff --git a/packages/validator/src/number.js b/packages/validator/src/number.js index dbf7b97ba3971a5be4da6ac3d9a463b4e57c5604..8bcefde262800a11749172fe9459ab1493d636da 100644 --- a/packages/validator/src/number.js +++ b/packages/validator/src/number.js @@ -1,6 +1,6 @@ // validator numbers // import { NUMBER_TYPES } from './constants'; -import { isNaN, isString } from 'lodash-es' +import { isNaN, isString } from './lodash' /** * @2015-05-04 found a problem if the value is a number like string * it will pass, so add a check if it's string before we pass to next diff --git a/packages/validator/src/object.js b/packages/validator/src/object.js index 1ff7be8cdbca846273c6032870789f0a345871e7..59ef9ccde3d6d42433894af5b7a8e6d0cb87dd32 100644 --- a/packages/validator/src/object.js +++ b/packages/validator/src/object.js @@ -1,5 +1,5 @@ // validate object type -import { isPlainObject, isUndefined, filter } from 'lodash-es' +import { isPlainObject, isUndefined, filter } from './lodash' import combineFn from './combine' import { checkIsArray, isArrayLike, arrayTypeHandler } from './array' /** diff --git a/packages/validator/src/options/check-options-async.js b/packages/validator/src/options/check-options-async.js index 23815b6773979f4712e21d6239cd93702e091e72..c29fcf2920e65fb628802b4e6a43f07fde7223f0 100644 --- a/packages/validator/src/options/check-options-async.js +++ b/packages/validator/src/options/check-options-async.js @@ -1,5 +1,5 @@ -// this is port back from the client to share across all projects -import { merge } from 'lodash-es' +/// this is port back from the client to share across all projects +import { merge } from '../lodash' import { prepareArgsForValidation } from './prepare-args-for-validation' import runValidation from './run-validation' diff --git a/packages/validator/src/options/check-options-sync.js b/packages/validator/src/options/check-options-sync.js index 7e9efaa365ecf1bb8f5c22b532fb2a1936a41017..5ba891a93e6ea97b697a3bd29a985fa076fff673 100644 --- a/packages/validator/src/options/check-options-sync.js +++ b/packages/validator/src/options/check-options-sync.js @@ -1,5 +1,5 @@ // this is port back from the client to share across all projects -import { merge } from 'lodash-es' +import { merge } from '../lodash' import { prepareArgsForValidation } from './prepare-args-for-validation' import runValidation from './run-validation' diff --git a/packages/validator/src/options/construct-config.js b/packages/validator/src/options/construct-config.js index 6e0fb1f8c88626fa29834f648e843602463d70c8..9fe5a0bd07d789c6692867f85faba5921dc919f0 100644 --- a/packages/validator/src/options/construct-config.js +++ b/packages/validator/src/options/construct-config.js @@ -1,5 +1,5 @@ // create function to construct the config entry so we don't need to keep building object -import { isFunction, isString } from 'lodash-es' +import { isFunction, isString } from '../lodash' import { ARGS_KEY, TYPE_KEY, diff --git a/packages/validator/src/options/prepare-args-for-validation.js b/packages/validator/src/options/prepare-args-for-validation.js index 389f76d85a482b4cbce8dfeec1ced0c537c9a4f4..36266c19ef7e0311c036d302f0bfebce32872c90 100644 --- a/packages/validator/src/options/prepare-args-for-validation.js +++ b/packages/validator/src/options/prepare-args-for-validation.js @@ -6,8 +6,7 @@ import { omitBy, isEqual, findKey -} from 'lodash-es' -import { isKeyInObject } from 'jsonql-utils' +} from '../lodash' import { TYPE_KEY, @@ -20,9 +19,7 @@ import { } from '../constants' import notEmpty from '../not-empty' import { checkIsObject } from '../object' - -// import debug from 'debug'; -// const debugFn = debug('jsonql-params-validator:options:prepare') +import isKeyInObject from '../is-key-in-object' // just not to make my head hurt const isEmpty = value => !notEmpty(value) diff --git a/packages/validator/src/options/run-validation.js b/packages/validator/src/options/run-validation.js index 2709166eb60c3f9059df1c9a5564fb712c996299..baac38cb4eba229c2ed348b0d9ca3362e469b330 100644 --- a/packages/validator/src/options/run-validation.js +++ b/packages/validator/src/options/run-validation.js @@ -1,6 +1,6 @@ // breaking the whole thing up to see what cause the multiple calls issue -import { isFunction, merge, mapValues } from 'lodash-es' +import { isFunction, merge, mapValues } from '../lodash' import { JsonqlEnumError, JsonqlTypeError, diff --git a/packages/validator/src/string.js b/packages/validator/src/string.js index e8a87b34dfa077dfb4e4ec0ec0c72d8d8a1f2c6e..297a7a35f230399c26a7b402e556aaa306250fcb 100644 --- a/packages/validator/src/string.js +++ b/packages/validator/src/string.js @@ -1,5 +1,5 @@ // validate string type -import { isString, trim } from 'lodash-es' +import { isString, trim } from './lodash' /** * @param {string} value expected value * @return {boolean} true if OK diff --git a/packages/validator/src/validator.js b/packages/validator/src/validator.js index 4b98f0facf1631b71fc03fe44393bd4573652bfb..04233158d740ffa795d45ea8c4e1aea3a8fe4073 100644 --- a/packages/validator/src/validator.js +++ b/packages/validator/src/validator.js @@ -1,5 +1,5 @@ // move the index.js code here that make more sense to find where things are -import { isUndefined } from 'lodash-es' +import { isUndefined } from './lodash' import { checkIsArray, isArrayLike, diff --git a/packages/validator/tests/fixtures/html/index.html b/packages/validator/tests/fixtures/html/index.html index b6b05f0ebc28e60f99c2181c3cfc5c39c34256d5..a98cde0190af164a1fed2f1303b8516564c35915 100644 --- a/packages/validator/tests/fixtures/html/index.html +++ b/packages/validator/tests/fixtures/html/index.html @@ -24,7 +24,7 @@ } $(function() { - // console.info(jsonqlParamsValidator); + console.info(jsonqlParamsValidator); var validateAsync = jsonqlParamsValidator.validateAsync; var tests = [ @@ -57,6 +57,7 @@ showResult(i, true, result.length); }) .catch(function(err) { + console.log(err) showResult(i, false, err.toString()); }); }