diff --git a/packages/ws-server/lib/socket-io/add-property.js b/packages/@jsonql/socketio/src/io/socket-io/add-property.js similarity index 100% rename from packages/ws-server/lib/socket-io/add-property.js rename to packages/@jsonql/socketio/src/io/socket-io/add-property.js diff --git a/packages/ws-server/lib/socket-io/index.js b/packages/@jsonql/socketio/src/io/socket-io/index.js similarity index 100% rename from packages/ws-server/lib/socket-io/index.js rename to packages/@jsonql/socketio/src/io/socket-io/index.js diff --git a/packages/ws-server/lib/socket-io/socket-io-create-server.js b/packages/@jsonql/socketio/src/io/socket-io/socket-io-create-server.js similarity index 100% rename from packages/ws-server/lib/socket-io/socket-io-create-server.js rename to packages/@jsonql/socketio/src/io/socket-io/socket-io-create-server.js diff --git a/packages/ws-server/lib/socket-io/socket-io-setup.js b/packages/@jsonql/socketio/src/io/socket-io/socket-io-setup.js similarity index 100% rename from packages/ws-server/lib/socket-io/socket-io-setup.js rename to packages/@jsonql/socketio/src/io/socket-io/socket-io-setup.js diff --git a/packages/ws-server/tests/socket-io-handshake.test.js b/packages/@jsonql/socketio/tests/socket-io-handshake.test.js similarity index 100% rename from packages/ws-server/tests/socket-io-handshake.test.js rename to packages/@jsonql/socketio/tests/socket-io-handshake.test.js diff --git a/packages/ws-server/tests/socket-io-roundtrip.test.js b/packages/@jsonql/socketio/tests/socket-io-roundtrip.test.js similarity index 100% rename from packages/ws-server/tests/socket-io-roundtrip.test.js rename to packages/@jsonql/socketio/tests/socket-io-roundtrip.test.js diff --git a/packages/ws-server/tests/socket-io.test.js b/packages/@jsonql/socketio/tests/socket-io.test.js similarity index 100% rename from packages/ws-server/tests/socket-io.test.js rename to packages/@jsonql/socketio/tests/socket-io.test.js diff --git a/packages/constants/README.md b/packages/constants/README.md index 1435c8bcc89a836f28444c4c2e7981048d94efc0..78beb4dbfdd0fff4ded9fdc7acb1eefe969c2b12 100755 --- a/packages/constants/README.md +++ b/packages/constants/README.md @@ -97,6 +97,8 @@ non-javascript to develop your tool. You can also use the included `constants.js - EMIT_REPLY_TYPE - ACKNOWLEDGE_REPLY_TYPE - ERROR_TYPE +- NSP_SET +- PUBLIC_NAMESPACE - JS_WS_SOCKET_IO_NAME - JS_WS_NAME - JS_PRIMUS_NAME diff --git a/packages/constants/constants.json b/packages/constants/constants.json index 900915a7a9dcb7ba89f1534992b71576a098938f..f82ac1901484925a0433f4e6ddec71baba208d7f 100644 --- a/packages/constants/constants.json +++ b/packages/constants/constants.json @@ -129,6 +129,8 @@ "EMIT_REPLY_TYPE": "emit", "ACKNOWLEDGE_REPLY_TYPE": "acknowledge", "ERROR_TYPE": "error", + "NSP_SET": "nspSet", + "PUBLIC_NAMESPACE": "publicNamespace", "JS_WS_SOCKET_IO_NAME": "socket.io", "JS_WS_NAME": "ws", "JS_PRIMUS_NAME": "primus", diff --git a/packages/constants/main.js b/packages/constants/main.js index 504056840bf07cb4b06f224f7d1891f89e7de5c3..bc497f1ba5c248af3ce3a4916f0bd4d3e1f2ac8a 100644 --- a/packages/constants/main.js +++ b/packages/constants/main.js @@ -129,6 +129,8 @@ module.exports = { "EMIT_REPLY_TYPE": "emit", "ACKNOWLEDGE_REPLY_TYPE": "acknowledge", "ERROR_TYPE": "error", + "NSP_SET": "nspSet", + "PUBLIC_NAMESPACE": "publicNamespace", "JS_WS_SOCKET_IO_NAME": "socket.io", "JS_WS_NAME": "ws", "JS_PRIMUS_NAME": "primus", diff --git a/packages/constants/module.js b/packages/constants/module.js index 18018b9fba8b88bd0ad90d334441f8699e827ffb..f56525f846ee40a14c6c7e013cae6d94e00a8553 100644 --- a/packages/constants/module.js +++ b/packages/constants/module.js @@ -131,6 +131,9 @@ export const EMIT_REPLY_TYPE = 'emit'; export const ACKNOWLEDGE_REPLY_TYPE = 'acknowledge'; export const ERROR_TYPE = 'error'; +export const NSP_SET = 'nspSet' +export const PUBLIC_NAMESPACE = 'publicNamespace' + export const JS_WS_SOCKET_IO_NAME = 'socket.io'; export const JS_WS_NAME = 'ws'; export const JS_PRIMUS_NAME = 'primus' diff --git a/packages/constants/package.json b/packages/constants/package.json index 47d6965d41e78e674c998104f3983f19dbea18a6..234eae0ce80d41e1841482885e7c1b015cf79ba9 100755 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-constants", - "version": "1.8.3", + "version": "1.8.4", "description": "All the share constants for json:ql tools", "main": "main.js", "module": "module.js", diff --git a/packages/koa/src/middlewares/file-middleware.js b/packages/koa/src/middlewares/file-middleware.js new file mode 100644 index 0000000000000000000000000000000000000000..6db8b3858968925e2447a0327007af9c3c51ad93 --- /dev/null +++ b/packages/koa/src/middlewares/file-middleware.js @@ -0,0 +1,29 @@ +// new file upload middleware that will get hook into +// our jwt authorization system +import fs from 'fs' +import os from 'os' +import { join } from 'path' + +import { API_REQUEST_METHODS } from 'jsonql-constants' +const [ POST ] = API_REQUEST_METHODS; + + +export default function fileMiddleware(opts) { + return async function(ctx, next) { + if (opts.useFileUpload) { + if (POST != ctx.method) { + return await next() + } + // should expect an array + const file = ctx.request.files[config.fileUploadName] + const tmpDir = config.fileUploadDist || join(os.tmpdir(), Math.random().toString()) + const reader = fs.createReadStream(file.path) + const stream = fs.createWriteStream(tmpDir) + + reader.pipe(stream) + + debug('uploading %s -> %s', file.name, stream.path) + } + await next() + } +} diff --git a/packages/koa/src/middlewares/index.js b/packages/koa/src/middlewares/index.js index 1b90a4958205cfc3da2ffa5c1f8f35820ea43af8..07d6acdbb86278bae3bf867e400aadfd9728e6fb 100644 --- a/packages/koa/src/middlewares/index.js +++ b/packages/koa/src/middlewares/index.js @@ -4,23 +4,21 @@ import coreMiddleware from './core-middleware' import contractMiddleware from './contract-middleware' import helloMiddleware from './hello-middleware' - import consoleMiddleware from './console-middleware' import publicMethodMiddleware from './public-method-middleware' // import errorsHandlerMiddleware from './errors-handler-middleware' import initMiddleware from './init-middleware' +// @1.4.0 file middleware +import fileMiddleware from './file-middleware' // export export { - // configCheck, - consoleMiddleware, authMiddleware, coreMiddleware, contractMiddleware, helloMiddleware, - publicMethodMiddleware, - // errorsHandlerMiddleware, - initMiddleware + initMiddleware, + fileMiddleware } diff --git a/packages/koa/src/options/options.js b/packages/koa/src/options/options.js index 36c6afbccea6d6cd18feb79f532f77715a6bda45..3c6a75d0182c935005924b7136895167bf2e8f81 100644 --- a/packages/koa/src/options/options.js +++ b/packages/koa/src/options/options.js @@ -102,8 +102,12 @@ const appProps = { buildContractOnStart: {[ARGS_KEY]: false, [TYPE_KEY]: BOOLEAN_TYPE}, // process.env.NODE_ENV === 'development', keepLastContract: {[ARGS_KEY]: false, [TYPE_KEY]: BOOLEAN_TYPE}, // true keep last one, integer > 0 keep that number of files validateReturns: {[ARGS_KEY]: false, [TYPE_KEY]: BOOLEAN_TYPE}, // reserved for use in the future - // For v1.5.0 to integrate the node-client - clientConfig: createConfig([], [ARRAY_TYPE]) + // For v1.3.x to integrate the node-client + clientConfig: createConfig([], [ARRAY_TYPE]), + // @1.4.0 switch on the file upload + useFileUpload: createConfig(false, [BOOLEAN_TYPE]), + fileUploadName: createConfig('file', [STRING_TYPE]), + fileUploadDist: createConfig(false, [STRING_TYPE]) }; const jwtProcessKey = 'INIT_JWT_KEYS' // just for id the promise call export { diff --git a/packages/resolver/index.js b/packages/resolver/index.js index 4a6096c93c0a74bcdbc94b11603b937feefbb68b..401c3eb9cf711673d11a33f8de3f8435ec9d5170 100644 --- a/packages/resolver/index.js +++ b/packages/resolver/index.js @@ -1,6 +1,8 @@ -const searchResolvers = require('./src/search-resolvers') -const validateAndCall = require('./src/validate-and-call') +// The final export API +const { searchResolvers } = require('./src/search-resolvers') +const { validateAndCall } = require('./src/validate-and-call') const { + getResolver, executeResolver, resolverRenderHandler } = require('./src/resolve-methods') @@ -11,9 +13,10 @@ const { // @TODO use the same for the jsonql-ws-server as well module.exports = { - handleAuthMethods, - validateAndCall, searchResolvers, + validateAndCall, + getResolver, + handleAuthMethods, getLocalValidator, executeResolver, resolverRenderHandler, diff --git a/packages/resolver/package.json b/packages/resolver/package.json index db5c833f8609d7eda5912c486fae12eacf543bbf..d1d4a55c6d1e5f98f09fc555fa28a0f94860744d 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-resolver", - "version": "0.9.3", + "version": "0.9.4", "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": [ diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index b0be78fa35ba0af369386f50ec45efa5a4f44194..7d2594c83709f1c9a3b69a38d1b28e86c1b02b2a 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -26,6 +26,33 @@ const { provideNodeClients } = require('./provide-node-clients') const debug = getDebug('resolve-method') +/** + * provide the require param then return the resolver function for use + * @param {string} resolverName name of resolver + * @param {string} type of resolver + * @param {object} contract the contract + * @param {object} opts configuration + * @return {function} resolver + */ +const getResolver = (resolverName, type, contract, opts) => { + try { + const { sourceType } = contract; + if (sourceType === MODULE_TYPE) { + /* + const { resolverDir } = opts; + fn = importFromModule(resolverDir, type, resolverName) + */ + const pathToResolver = findFromContract(type, resolverName, contract) + debug('call requireEsModule', resolverName, pathToResolver) + return requireEsModule(pathToResolver) + } + + return require(searchResolvers(resolverName, type, opts, contract)) + } catch(e) { + throw new JsonqlResolverNotFoundError(e) + } +} + /** * A new method breaking out the get resolver and prepare code * then make the original resolveMethod as a koa render handler @@ -38,19 +65,7 @@ const debug = getDebug('resolve-method') * @return {*} result - process result from resolver */ const executeResolver = (opts, type, resolverName, payload, contract, userdata = false) => { - let fn; - const { sourceType } = contract; - if (sourceType === MODULE_TYPE) { - /* - const { resolverDir } = opts; - fn = importFromModule(resolverDir, type, resolverName) - */ - const pathToResolver = findFromContract(type, resolverName, contract) - debug('call requireEsModule', resolverName, pathToResolver) - fn = requireEsModule(pathToResolver) - } else { - fn = require(searchResolvers(resolverName, type, opts, contract)) - } + const fn = getResolver(resolverName, type, contract, opts) const args = extractArgsFromPayload(payload, type) // inject the node client if any // @0.9.0 change everything to promise and stop using async @@ -109,6 +124,7 @@ async function resolverRenderHandler(ctx, type, opts, contract) { // named export instead module.exports = { + getResolver, executeResolver, resolverRenderHandler } diff --git a/packages/resolver/tests/fixtures/contract/es/contract.json b/packages/resolver/tests/fixtures/contract/es/contract.json index d8d8966563561314302239af2ffebdbf00241d04..8f2d3dd8248988c111d5369fab1e1ea6de366ccb 100644 --- a/packages/resolver/tests/fixtures/contract/es/contract.json +++ b/packages/resolver/tests/fixtures/contract/es/contract.json @@ -43,6 +43,6 @@ } }, "auth": {}, - "timestamp": 1570528682, + "timestamp": 1570635866, "sourceType": "module" } diff --git a/packages/utils/browser.js b/packages/utils/browser.js index 7e526b7a0dcf36bb25ebff0d8dd2ace8d4173f2b..9d9c13bba4a5d9feb0ab9fc5aca9c436865e514b 100644 --- a/packages/utils/browser.js +++ b/packages/utils/browser.js @@ -1,2 +1,2 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlUtils={})}(this,(function(t){"use strict";var r=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")(),i=u.Symbol,a=Object.prototype,c=a.hasOwnProperty,f=a.toString,s=i?i.toStringTag:void 0;var l=Object.prototype.toString;var p="[object Null]",v="[object Undefined]",d=i?i.toStringTag:void 0;function y(t){return null==t?void 0===t?v:p:d&&d in Object(t)?function(t){var r=c.call(t,s),e=t[s];try{t[s]=void 0;var n=!0}catch(t){}var o=f.call(t);return n&&(r?t[s]=e:delete t[s]),o}(t):function(t){return l.call(t)}(t)}var h,b,_=(h=Object.getPrototypeOf,b=Object,function(t){return h(b(t))});function g(t){return null!=t&&"object"==typeof t}var j="[object Object]",m=Function.prototype,O=Object.prototype,w=m.toString,P=O.hasOwnProperty,S=w.call(Object);function A(t){if(!g(t)||y(t)!=j)return!1;var r=_(t);if(null===r)return!0;var e=P.call(r,"constructor")&&r.constructor;return"function"==typeof e&&e instanceof e&&w.call(e)==S}var k="[object Symbol]";var z=1/0,E=i?i.prototype:void 0,N=E?E.toString:void 0;function F(t){if("string"==typeof t)return t;if(r(t))return function(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e=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 u=Array(o);++n-1;);return e}(o,u),function(t,r){for(var e=t.length;e--&&C(r,t[e],0)>-1;);return e}(o,u)+1).join("")}var K="[object String]";function W(t){return"string"==typeof t||!r(t)&&g(t)&&y(t)==K}function Z(t,r){return t===r||t!=t&&r!=r}function X(t,r){for(var e=t.length;e--;)if(Z(t[e][0],r))return e;return-1}var Y=Array.prototype.splice;function tt(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},tt.prototype.set=function(t,r){var e=this.__data__,n=X(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this};var et="[object AsyncFunction]",nt="[object Function]",ot="[object GeneratorFunction]",ut="[object Proxy]";function it(t){if(!rt(t))return!1;var r=y(t);return r==nt||r==ot||r==et||r==ut}var at,ct=u["__core-js_shared__"],ft=(at=/[^.]+$/.exec(ct&&ct.keys&&ct.keys.IE_PROTO||""))?"Symbol(src)_1."+at:"";var st=Function.prototype.toString;var lt=/^\[object .+?Constructor\]$/,pt=Function.prototype,vt=Object.prototype,dt=pt.toString,yt=vt.hasOwnProperty,ht=RegExp("^"+dt.call(yt).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function bt(t){return!(!rt(t)||function(t){return!!ft&&ft in t}(t))&&(it(t)?ht:lt).test(function(t){if(null!=t){try{return st.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function _t(t,r){var e=function(t,r){return null==t?void 0:t[r]}(t,r);return bt(e)?e:void 0}var gt=_t(u,"Map"),jt=_t(Object,"create");var mt="__lodash_hash_undefined__",Ot=Object.prototype.hasOwnProperty;var wt=Object.prototype.hasOwnProperty;var Pt="__lodash_hash_undefined__";function St(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1&&t%1==0&&t<=Zt}function Yt(t){return null!=t&&Xt(t.length)&&!it(t)}var tr="object"==typeof t&&t&&!t.nodeType&&t,rr=tr&&"object"==typeof module&&module&&!module.nodeType&&module,er=rr&&rr.exports===tr?u.Buffer:void 0,nr=(er?er.isBuffer:void 0)||function(){return!1},or={};or["[object Float32Array]"]=or["[object Float64Array]"]=or["[object Int8Array]"]=or["[object Int16Array]"]=or["[object Int32Array]"]=or["[object Uint8Array]"]=or["[object Uint8ClampedArray]"]=or["[object Uint16Array]"]=or["[object Uint32Array]"]=!0,or["[object Arguments]"]=or["[object Array]"]=or["[object ArrayBuffer]"]=or["[object Boolean]"]=or["[object DataView]"]=or["[object Date]"]=or["[object Error]"]=or["[object Function]"]=or["[object Map]"]=or["[object Number]"]=or["[object Object]"]=or["[object RegExp]"]=or["[object Set]"]=or["[object String]"]=or["[object WeakMap]"]=!1;var ur="object"==typeof t&&t&&!t.nodeType&&t,ir=ur&&"object"==typeof module&&module&&!module.nodeType&&module,ar=ir&&ir.exports===ur&&n.process,cr=function(){try{var t=ir&&ir.require&&ir.require("util").types;return t||ar&&ar.binding&&ar.binding("util")}catch(t){}}(),fr=cr&&cr.isTypedArray,sr=fr?function(t){return function(r){return t(r)}}(fr):function(t){return g(t)&&Xt(t.length)&&!!or[y(t)]};function lr(t,r){if(("constructor"!==r||"function"!=typeof t[r])&&"__proto__"!=r)return t[r]}var pr=Object.prototype.hasOwnProperty;function vr(t,r,e){var n=t[r];pr.call(t,r)&&Z(n,e)&&(void 0!==e||r in t)||Ft(t,r,e)}var dr=9007199254740991,yr=/^(?:0|[1-9]\d*)$/;function hr(t,r){var e=typeof t;return!!(r=null==r?dr:r)&&("number"==e||"symbol"!=e&&yr.test(t))&&t>-1&&t%1==0&&t0){if(++r>=Er)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(zr);function Tr(t,r){return xr(function(t,r,e){return r=kr(void 0===r?t.length-1:r,0),function(){for(var n=arguments,o=-1,u=kr(n.length-r,0),i=Array(u);++o1?r[n-1]:void 0,u=n>2?r[2]:void 0;for(o=Cr.length>3&&"function"==typeof o?(n--,o):void 0,u&&function(t,r,e){if(!rt(e))return!1;var n=typeof r;return!!("number"==n?Yt(e)&&hr(r,e.length):"string"==n&&r in e)&&Z(e[r],t)}(r[0],r[1],u)&&(o=n<3?void 0:o,n=1),t=Object(t);++e0;)r[e]=arguments[e+1];return function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return r.reduce((function(t,r){return Reflect.apply(r,null,[t])}),Reflect.apply(t,null,e))}},t.chainPromises=function(t,r){return void 0===r&&(r=!1),t.reduce((function(t,e){return t.then((function(t){return e.then((function(e){return!1===r?t.concat([e]):Mr(t,e)}))}))}),Promise.resolve(!1===r?[]:A(r)?r:{}))},t.checkIsContract=re,t.createEvt=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return t.join("_")},t.createMutation=ae,t.createMutationStr=function(t,r,e,n){return void 0===e&&(e={}),void 0===n&&(n=!1),JSON.stringify(ae(t,r,e,n))},t.createQuery=ie,t.createQueryStr=function(t,r,e){return void 0===r&&(r=[]),void 0===e&&(e=!1),JSON.stringify(ie(t,r,e))},t.dasherize=function(t){return H(t).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},t.extractArgsFromPayload=function(t,r){switch(r){case Br:return t[Gr];case Ir:return[t[Qr],t[Vr]];default:throw new te("Unknown "+r+" to extract argument from!")}},t.extractParamsFromContract=function(t,r,e){try{var n=t[r][e];if(!n)throw new Xr(e,r);return n}catch(t){throw new Xr(e,t)}},t.extractSocketPart=ee,t.formatPayload=oe,t.getCallMethod=function(t){switch(!0){case t===Hr[0]:return Br;case t===Hr[1]:return Ir;default:return!1}},t.getConfigValue=function(t,r){return r&&A(r)&&t in r?r[t]:void 0},t.getMutationFromArgs=se,t.getMutationFromPayload=function(t){var r=fe(t,se);if(!1!==r)return r;throw new Yr("[getMutationArgs] Payload is malformed!",t)},t.getNameFromPayload=ue,t.getQueryFromArgs=ce,t.getQueryFromPayload=function(t){var r=fe(t,ce);if(!1!==r)return r;throw new Yr("[getQueryArgs] Payload is malformed!",t)},t.groupByNamespace=function(t,r){void 0===r&&(r=!1);var e=ee(t);if(!1===e){if(r)return t;throw new te("socket not found in contract!")}var n,o={},u=0;for(var i in e){var a=e[i],c=a.namespace;c&&(o[c]||(++u,o[c]={}),o[c][i]=a,n||a.public&&(n=c))}return{size:u,nspSet:o,publicNamespace:n}},t.inArray=Rr,t.injectToFn=function(t,r,e,n){void 0===n&&(n=!1);var o=Object.getOwnPropertyDescriptor(t,r);return!1===n&&void 0!==o?t:(Object.defineProperty(t,r,{value:e,writable:n}),t)},t.isContract=le,t.isKeyInObject=Ur,t.isNotEmpty=function(t){return void 0!==t&&!1!==t&&null!==t&&""!==H(t)},t.objDefineProps=function(t,r,e,n){return void 0===n&&(n=null),void 0===Object.getOwnPropertyDescriptor(t,r)&&Object.defineProperty(t,r,{set:e,get:null===n?function(){return null}:n}),t},t.packError=function(t,r,e,n){var o;return void 0===r&&(r="JsonqlError"),void 0===e&&(e=500),void 0===n&&(n=""),JSON.stringify(((o={}).error={detail:t,className:r,statusCode:e,message:n},o))},t.packResult=function(t){var r;return JSON.stringify(((r={}).data=t,r))},t.resultHandler=function(t){return Ur(t,"data")&&!Ur(t,"error")?t.data:t},t.timestamp=Jr,t.toPayload=ne,t.urlParams=$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).jsonqlUtils={})}(this,(function(t){"use strict";var r=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")(),i=u.Symbol,a=Object.prototype,c=a.hasOwnProperty,f=a.toString,s=i?i.toStringTag:void 0;var l=Object.prototype.toString;var p="[object Null]",v="[object Undefined]",d=i?i.toStringTag:void 0;function y(t){return null==t?void 0===t?v:p:d&&d in Object(t)?function(t){var r=c.call(t,s),e=t[s];try{t[s]=void 0;var n=!0}catch(t){}var o=f.call(t);return n&&(r?t[s]=e:delete t[s]),o}(t):function(t){return l.call(t)}(t)}var h,b,g=(h=Object.getPrototypeOf,b=Object,function(t){return h(b(t))});function _(t){return null!=t&&"object"==typeof t}var j="[object Object]",m=Function.prototype,O=Object.prototype,w=m.toString,P=O.hasOwnProperty,S=w.call(Object);function A(t){if(!_(t)||y(t)!=j)return!1;var r=g(t);if(null===r)return!0;var e=P.call(r,"constructor")&&r.constructor;return"function"==typeof e&&e instanceof e&&w.call(e)==S}var N="[object Symbol]";var E=1/0,k=i?i.prototype:void 0,z=k?k.toString:void 0;function F(t){if("string"==typeof t)return t;if(r(t))return function(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e=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 u=Array(o);++n-1;);return e}(o,u),function(t,r){for(var e=t.length;e--&&C(r,t[e],0)>-1;);return e}(o,u)+1).join("")}var K="[object String]";function W(t){return"string"==typeof t||!r(t)&&_(t)&&y(t)==K}function Z(t,r){return t===r||t!=t&&r!=r}function X(t,r){for(var e=t.length;e--;)if(Z(t[e][0],r))return e;return-1}var Y=Array.prototype.splice;function tt(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},tt.prototype.set=function(t,r){var e=this.__data__,n=X(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this};var et="[object AsyncFunction]",nt="[object Function]",ot="[object GeneratorFunction]",ut="[object Proxy]";function it(t){if(!rt(t))return!1;var r=y(t);return r==nt||r==ot||r==et||r==ut}var at,ct=u["__core-js_shared__"],ft=(at=/[^.]+$/.exec(ct&&ct.keys&&ct.keys.IE_PROTO||""))?"Symbol(src)_1."+at:"";var st=Function.prototype.toString;var lt=/^\[object .+?Constructor\]$/,pt=Function.prototype,vt=Object.prototype,dt=pt.toString,yt=vt.hasOwnProperty,ht=RegExp("^"+dt.call(yt).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function bt(t){return!(!rt(t)||function(t){return!!ft&&ft in t}(t))&&(it(t)?ht:lt).test(function(t){if(null!=t){try{return st.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function gt(t,r){var e=function(t,r){return null==t?void 0:t[r]}(t,r);return bt(e)?e:void 0}var _t=gt(u,"Map"),jt=gt(Object,"create");var mt="__lodash_hash_undefined__",Ot=Object.prototype.hasOwnProperty;var wt=Object.prototype.hasOwnProperty;var Pt="__lodash_hash_undefined__";function St(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1&&t%1==0&&t<=Zt}function Yt(t){return null!=t&&Xt(t.length)&&!it(t)}var tr="object"==typeof t&&t&&!t.nodeType&&t,rr=tr&&"object"==typeof module&&module&&!module.nodeType&&module,er=rr&&rr.exports===tr?u.Buffer:void 0,nr=(er?er.isBuffer:void 0)||function(){return!1},or={};or["[object Float32Array]"]=or["[object Float64Array]"]=or["[object Int8Array]"]=or["[object Int16Array]"]=or["[object Int32Array]"]=or["[object Uint8Array]"]=or["[object Uint8ClampedArray]"]=or["[object Uint16Array]"]=or["[object Uint32Array]"]=!0,or["[object Arguments]"]=or["[object Array]"]=or["[object ArrayBuffer]"]=or["[object Boolean]"]=or["[object DataView]"]=or["[object Date]"]=or["[object Error]"]=or["[object Function]"]=or["[object Map]"]=or["[object Number]"]=or["[object Object]"]=or["[object RegExp]"]=or["[object Set]"]=or["[object String]"]=or["[object WeakMap]"]=!1;var ur="object"==typeof t&&t&&!t.nodeType&&t,ir=ur&&"object"==typeof module&&module&&!module.nodeType&&module,ar=ir&&ir.exports===ur&&n.process,cr=function(){try{var t=ir&&ir.require&&ir.require("util").types;return t||ar&&ar.binding&&ar.binding("util")}catch(t){}}(),fr=cr&&cr.isTypedArray,sr=fr?function(t){return function(r){return t(r)}}(fr):function(t){return _(t)&&Xt(t.length)&&!!or[y(t)]};function lr(t,r){if(("constructor"!==r||"function"!=typeof t[r])&&"__proto__"!=r)return t[r]}var pr=Object.prototype.hasOwnProperty;function vr(t,r,e){var n=t[r];pr.call(t,r)&&Z(n,e)&&(void 0!==e||r in t)||Ft(t,r,e)}var dr=9007199254740991,yr=/^(?:0|[1-9]\d*)$/;function hr(t,r){var e=typeof t;return!!(r=null==r?dr:r)&&("number"==e||"symbol"!=e&&yr.test(t))&&t>-1&&t%1==0&&t0){if(++r>=kr)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(Er);function Tr(t,r){return xr(function(t,r,e){return r=Nr(void 0===r?t.length-1:r,0),function(){for(var n=arguments,o=-1,u=Nr(n.length-r,0),i=Array(u);++o1?r[n-1]:void 0,u=n>2?r[2]:void 0;for(o=Cr.length>3&&"function"==typeof o?(n--,o):void 0,u&&function(t,r,e){if(!rt(e))return!1;var n=typeof r;return!!("number"==n?Yt(e)&&hr(r,e.length):"string"==n&&r in e)&&Z(e[r],t)}(r[0],r[1],u)&&(o=n<3?void 0:o,n=1),t=Object(t);++e0;)r[e]=arguments[e+1];return function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return r.reduce((function(t,r){return Reflect.apply(r,null,[t])}),Reflect.apply(t,null,e))}},t.chainPromises=function(t,r){return void 0===r&&(r=!1),t.reduce((function(t,e){return t.then((function(t){return e.then((function(e){return!1===r?t.concat([e]):Jr(t,e)}))}))}),Promise.resolve(!1===r?[]:A(r)?r:{}))},t.checkIsContract=re,t.createEvt=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return t.join("_")},t.createMutation=ae,t.createMutationStr=function(t,r,e,n){return void 0===e&&(e={}),void 0===n&&(n=!1),JSON.stringify(ae(t,r,e,n))},t.createQuery=ie,t.createQueryStr=function(t,r,e){return void 0===r&&(r=[]),void 0===e&&(e=!1),JSON.stringify(ie(t,r,e))},t.dasherize=function(t){return H(t).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},t.extractArgsFromPayload=function(t,r){switch(r){case $r:return t[Gr];case Br:return[t[Qr],t[Vr]];default:throw new te("Unknown "+r+" to extract argument from!")}},t.extractParamsFromContract=function(t,r,e){try{var n=t[r][e];if(!n)throw new Xr(e,r);return n}catch(t){throw new Xr(e,t)}},t.extractSocketPart=ee,t.formatPayload=oe,t.getCallMethod=function(t){switch(!0){case t===Hr[0]:return $r;case t===Hr[1]:return Br;default:return!1}},t.getConfigValue=function(t,r){return r&&A(r)&&t in r?r[t]:void 0},t.getMutationFromArgs=se,t.getMutationFromPayload=function(t){var r=fe(t,se);if(!1!==r)return r;throw new Yr("[getMutationArgs] Payload is malformed!",t)},t.getNameFromPayload=ue,t.getNamespaceInOrder=function(t,r){var e=[];for(var n in t)n===r?e[1]=n:e[0]=n;return e},t.getQueryFromArgs=ce,t.getQueryFromPayload=function(t){var r=fe(t,ce);if(!1!==r)return r;throw new Yr("[getQueryArgs] Payload is malformed!",t)},t.groupByNamespace=function(t,r){void 0===r&&(r=!1);var e=ee(t);if(!1===e){if(r)return t;throw new te("socket not found in contract!")}var n,o={},u=0;for(var i in e){var a=e[i],c=a.namespace;c&&(o[c]||(++u,o[c]={}),o[c][i]=a,n||a.public&&(n=c))}return{size:u,nspSet:o,publicNamespace:n}},t.inArray=Mr,t.injectToFn=function(t,r,e,n){void 0===n&&(n=!1);var o=Object.getOwnPropertyDescriptor(t,r);return!1===n&&void 0!==o?t:(Object.defineProperty(t,r,{value:e,writable:n}),t)},t.isContract=pe,t.isJsonqlErrorObj=le,t.isKeyInObject=Rr,t.isNotEmpty=function(t){return void 0!==t&&!1!==t&&null!==t&&""!==H(t)},t.objDefineProps=function(t,r,e,n){return void 0===n&&(n=null),void 0===Object.getOwnPropertyDescriptor(t,r)&&Object.defineProperty(t,r,{set:e,get:null===n?function(){return null}:n}),t},t.packError=function(t,r,e,n){var o;void 0===r&&(r="JsonqlError"),void 0===e&&(e=0),void 0===n&&(n="");var u={detail:t,className:r,statusCode:e,message:n};return JSON.stringify(((o={}).error=le(t)||u,o))},t.packResult=function(t){var r;return JSON.stringify(((r={}).data=t,r))},t.resultHandler=function(t){return Rr(t,"data")&&!Rr(t,"error")?t.data:t},t.timestamp=Ur,t.toJson=function(t){return"string"==typeof t?function(t){try{return JSON.parse(t)}catch(r){return t}}(t):JSON.parse(JSON.stringify(t))},t.toPayload=ne,t.urlParams=qr,Object.defineProperty(t,"__esModule",{value:!0})})); //# sourceMappingURL=browser.js.map diff --git a/packages/utils/debug.js b/packages/utils/debug.js index b50b81604a0903991cbf3ff4a35bf6f2f28174c5..cf6fa1e0eddd0b2fed71949cc9035b757b1a09a5 100644 --- a/packages/utils/debug.js +++ b/packages/utils/debug.js @@ -1,12 +1,52 @@ -import debug from 'debug' +// just try and get it +const getBaseName = () => { + try { // browser + return window.DEBUG_BASE_NAME + } catch(e) { + // ignore it + } + try { // node + if (global.DEBUG_BASE_NAME) { + return global.DEBUG_BASE_NAME + } else if (process.env.DEBUG_BASE_NAME) { + return process.env.DEBUG_BASE_NAME + } + } catch(e) { + // ignore it + } + return 'jsonql' // just a stock one +} /** - * @param {string} name the name part after the : - * @param {string} baseName the base before the : + * Try to normalize it to use between browser and node + * @param {string} name for the debug output + * @return {function} debug */ -export const getDebug = (name, baseName = 'jsonql') => { +const getDebug = (name) => { + const BASE_NAME = getBaseName() + try { + if (window.debug) { // the global browser object + return window.debug(BASE_NAME).extend(name) + } + } catch(e) { + // ignore this + } try { - return debug(baseName).extend(name) - } catch(e) {} - return () => {} // just return a fake function + if (global.debug) { + return global.debug(BASE_NAME).extend(name) + } + } catch(e) { + // ignore this + } + // just a stock one + return (...args) => { + console.info.apply(null, [BASE_NAME, name].concat(args)) + } } +try { + if (window && window.localStorage) { + localStorage.setItem('DEBUG', getBaseName() + '*') + } +} catch(e) {} +// export it +export default getDebug; diff --git a/packages/utils/index.js b/packages/utils/index.js index 13adde5b48d1fdcda42c9941e623b5db6761eea4..628732a61f7af8d62dca185aa1dcddb389079ad2 100644 --- a/packages/utils/index.js +++ b/packages/utils/index.js @@ -12,6 +12,7 @@ import { checkIsContract, extractSocketPart, groupByNamespace, + getNamespaceInOrder, isContract, // alias // generic inArray, @@ -24,6 +25,7 @@ import { cacheBurstUrl, getConfigValue, isNotEmpty, + toJson, // params-api toPayload, formatPayload, @@ -44,6 +46,7 @@ import { packResult, packError, resultHandler, + isJsonqlErrorObj, VERSION } from './module' import { buff } from './src/jwt' @@ -91,6 +94,7 @@ export { packResult, packError, resultHandler, + isJsonqlErrorObj, // chain-fns chainFns, chainPromises, @@ -100,6 +104,7 @@ export { checkIsContract, extractSocketPart, groupByNamespace, + getNamespaceInOrder, isContract, // alias // generic inArray, @@ -112,6 +117,7 @@ export { cacheBurstUrl, getConfigValue, isNotEmpty, + toJson, // params-api toPayload, formatPayload, diff --git a/packages/utils/main.js b/packages/utils/main.js index f59962f209c89e651dd532a86c1e5a8be050fd5f..6d8169fae710de5d386d6d9e5e7485bafbeadb52 100644 --- a/packages/utils/main.js +++ b/packages/utils/main.js @@ -1,2 +1,2 @@ -"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"),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 a=Array(o);++n=n?r:baseSlice(r,t,e)}function baseFindIndex(r,t,e,n){for(var o=r.length,a=e+(n?1:-1);n?a--:++a-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}function listCacheClear(){this.__data__=[],this.size=0}function eq(r,t){return r===t||r!=r&&t!=t}function assocIndexOf(r,t){for(var e=r.length;e--;)if(eq(r[e][0],t))return e;return-1}var arrayProto=Array.prototype,splice=arrayProto.splice;function listCacheDelete(r){var t=this.__data__,e=assocIndexOf(t,r);return!(e<0)&&(e==t.length-1?t.pop():splice.call(t,e,1),--this.size,!0)}function listCacheGet(r){var t=this.__data__,e=assocIndexOf(t,r);return e<0?void 0:t[e][1]}function listCacheHas(r){return assocIndexOf(this.__data__,r)>-1}function listCacheSet(r,t){var e=this.__data__,n=assocIndexOf(e,r);return n<0?(++this.size,e.push([r,t])):e[n][1]=t,this}function ListCache(r){var t=-1,e=null==r?0:r.length;for(this.clear();++t-1&&r%1==0&&r<=MAX_SAFE_INTEGER}function isArrayLike(r){return null!=r&&isLength(r.length)&&!isFunction(r)}function isArrayLikeObject(r){return isObjectLike(r)&&isArrayLike(r)}function stubFalse(){return!1}var freeExports$1="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule$1=freeExports$1&&"object"==typeof module&&module&&!module.nodeType&&module,moduleExports$1=freeModule$1&&freeModule$1.exports===freeExports$1,Buffer$1=moduleExports$1?root.Buffer:void 0,nativeIsBuffer=Buffer$1?Buffer$1.isBuffer:void 0,isBuffer=nativeIsBuffer||stubFalse,argsTag$1="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",funcTag$1="[object Function]",mapTag="[object Map]",numberTag="[object Number]",objectTag$1="[object Object]",regexpTag="[object RegExp]",setTag="[object Set]",stringTag$1="[object String]",weakMapTag="[object WeakMap]",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]",typedArrayTags={};function baseIsTypedArray(r){return isObjectLike(r)&&isLength(r.length)&&!!typedArrayTags[baseGetTag(r)]}function baseUnary(r){return function(t){return r(t)}}typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag$1]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag$1]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag$1]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag$1]=typedArrayTags[weakMapTag]=!1;var freeExports$2="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule$2=freeExports$2&&"object"==typeof module&&module&&!module.nodeType&&module,moduleExports$2=freeModule$2&&freeModule$2.exports===freeExports$2,freeProcess=moduleExports$2&&freeGlobal.process,nodeUtil=function(){try{var r=freeModule$2&&freeModule$2.require&&freeModule$2.require("util").types;return r||freeProcess&&freeProcess.binding&&freeProcess.binding("util")}catch(r){}}(),nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray,isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;function safeGet(r,t){if(("constructor"!==t||"function"!=typeof r[t])&&"__proto__"!=t)return r[t]}var objectProto$8=Object.prototype,hasOwnProperty$6=objectProto$8.hasOwnProperty;function assignValue(r,t,e){var n=r[t];hasOwnProperty$6.call(r,t)&&eq(n,e)&&(void 0!==e||t in r)||baseAssignValue(r,t,e)}function copyObject(r,t,e,n){var o=!e;e||(e={});for(var a=-1,i=t.length;++a-1&&r%1==0&&r0){if(++t>=HOT_COUNT)return arguments[0]}else t=0;return r.apply(void 0,arguments)}}var setToString=shortOut(baseSetToString);function baseRest(r,t){return setToString(overRest(r,t,identity),r+"")}function isIterateeCall(r,t,e){if(!isObject(e))return!1;var n=typeof t;return!!("number"==n?isArrayLike(e)&&isIndex(t,e.length):"string"==n&&t in e)&&eq(e[t],r)}function createAssigner(r){return baseRest((function(t,e){var n=-1,o=e.length,a=o>1?e[o-1]:void 0,i=o>2?e[2]:void 0;for(a=r.length>3&&"function"==typeof a?(o--,a):void 0,i&&isIterateeCall(e[0],e[1],i)&&(a=o<3?void 0:a,o=1),t=Object(t);++n0;)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,t){return void 0===t&&(t=!1),r.reduce((function(r,e){return r.then((function(r){return e.then((function(e){return!1===t?r.concat([e]):merge(r,e)}))}))}),Promise.resolve(!1===t?[]:isPlainObject(t)?t:{}))}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 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,a=t.message||NO_ERROR_MSG,i=t.detail||t;if(o&&errors[o])throw new errors[e](a,i);throw new JsonqlError$1(a,i)}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={},a=0;for(var i in e){var s=e[i],u=s.namespace;u&&(o[u]||(++a,o[u]={}),o[u][i]=s,n||s.public&&(n=u))}return{size:a,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 a={};if(a[PAYLOAD_PARAM_NAME]=t,a[CONDITION_PARAM_NAME]=e,!0===n)return a;if(isString(r))return(o={})[r]=a,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.12",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");a="="===r[s-2]?2:"="===r[s-1]?1:0,i=new Arr(3*s/4-a),n=a>0?s-4:s;var u=0;for(t=0,e=0;t>16&255,i[u++]=o>>8&255,i[u++]=255&o;return 2===a?(o=revLookup[r.charCodeAt(t)]<<2|revLookup[r.charCodeAt(t+1)]>>4,i[u++]=255&o):1===a&&(o=revLookup[r.charCodeAt(t)]<<10|revLookup[r.charCodeAt(t+1)]<<4|revLookup[r.charCodeAt(t+2)]>>2,i[u++]=o>>8&255,i[u++]=255&o),i}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=[],a=t;as?s:i+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+="="),a.push(o),a.join("")}function read(r,t,e,n,o){var a,i,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,a=p&(1<<-c)-1,p>>=-c,c+=s;c>0;a=256*a+r[t+l],l+=h,c-=8);for(i=a&(1<<-c)-1,a>>=-c,c+=n;c>0;i=256*i+r[t+l],l+=h,c-=8);if(0===a)a=1-f;else{if(a===u)return i?NaN:1/0*(p?-1:1);i+=Math.pow(2,n),a-=f}return(p?-1:1)*i*Math.pow(2,a-n)}function write(r,t,e,n,o,a){var i,s,u,f=8*a-o-1,c=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-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,i=c):(i=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-i))<1&&(i--,u*=2),(t+=i+l>=1?h/u:h*Math.pow(2,1-l))*u>=2&&(i++,u/=2),i+l>=c?(s=0,i=c):i+l>=1?(s=(t*u-1)*Math.pow(2,o),i+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,o),i=0));o>=8;r[e+p]=255&s,p+=g,s/=256,o-=8);for(i=i<0;r[e+p]=255&i,p+=g,i/=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$2.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$2.from(t,n)),internalIsBuffer(t))return 0===t.length?-1:arrayIndexOf(r,t,e,n,o);if("number"==typeof t)return t&=255,Buffer$2.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 a,i=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;i=2,s/=2,u/=2,e/=2}function f(r,t){return 1===i?r[t]:r.readUInt16BE(t*i)}if(o){var c=-1;for(a=e;as&&(e=s-u),a=e;a>=0;a--){for(var l=!0,h=0;ho&&(n=o):n=o;var a=t.length;if(a%2!=0)throw new TypeError("Invalid hex string");n>a/2&&(n=a/2);for(var i=0;i239?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&(a=r[o+1]))&&(u=(31&f)<<6|63&a)>127&&(c=u);break;case 3:a=r[o+1],i=r[o+2],128==(192&a)&&128==(192&i)&&(u=(15&f)<<12|(63&a)<<6|63&i)>2047&&(u<55296||u>57343)&&(c=u);break;case 4:a=r[o+1],i=r[o+2],s=r[o+3],128==(192&a)&&128==(192&i)&&128==(192&s)&&(u=(15&f)<<18|(63&a)<<12|(63&i)<<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$2.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer$2.poolSize=8192,Buffer$2._augment=function(r){return r.__proto__=Buffer$2.prototype,r},Buffer$2.from=function(r,t,e){return from(null,r,t,e)},Buffer$2.TYPED_ARRAY_SUPPORT&&(Buffer$2.prototype.__proto__=Uint8Array.prototype,Buffer$2.__proto__=Uint8Array),Buffer$2.alloc=function(r,t,e){return alloc(null,r,t,e)},Buffer$2.allocUnsafe=function(r){return allocUnsafe$1(null,r)},Buffer$2.allocUnsafeSlow=function(r){return allocUnsafe$1(null,r)},Buffer$2.isBuffer=isBuffer$1,Buffer$2.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,a=Math.min(e,n);o0&&(r=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(r+=" ... ")),""},Buffer$2.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 a=(o>>>=0)-(n>>>=0),i=(e>>>=0)-(t>>>=0),s=Math.min(a,i),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 a=!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(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(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="",a=t;ae)throw new RangeError("Trying to access beyond buffer length")}function checkInt(r,t,e,n,o,a){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,a=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,a=Math.min(r.length-e,4);o>>8*(n?o:3-o)&255}function checkIEEE754(r,t,e,n,o,a){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$2.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$2.prototype.readUInt8=function(r,t){return t||checkOffset(r,1,this.length),this[r]},Buffer$2.prototype.readUInt16LE=function(r,t){return t||checkOffset(r,2,this.length),this[r]|this[r+1]<<8},Buffer$2.prototype.readUInt16BE=function(r,t){return t||checkOffset(r,2,this.length),this[r]<<8|this[r+1]},Buffer$2.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$2.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$2.prototype.readIntLE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=this[r],o=1,a=0;++a=(o*=128)&&(n-=Math.pow(2,8*t)),n},Buffer$2.prototype.readIntBE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=t,o=1,a=this[r+--n];n>0&&(o*=256);)a+=this[r+--n]*o;return a>=(o*=128)&&(a-=Math.pow(2,8*t)),a},Buffer$2.prototype.readInt8=function(r,t){return t||checkOffset(r,1,this.length),128&this[r]?-1*(255-this[r]+1):this[r]},Buffer$2.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$2.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$2.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$2.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$2.prototype.readFloatLE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!0,23,4)},Buffer$2.prototype.readFloatBE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!1,23,4)},Buffer$2.prototype.readDoubleLE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!0,52,8)},Buffer$2.prototype.readDoubleBE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!1,52,8)},Buffer$2.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,a=0;for(this[t]=255&r;++a=0&&(a*=256);)this[t+o]=r/a&255;return t+e},Buffer$2.prototype.writeUInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,255,0),Buffer$2.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),this[t]=255&r,t+1},Buffer$2.prototype.writeUInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer$2.prototype.writeUInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer$2.prototype.writeUInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer$2.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$2.prototype.writeUInt32BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer$2.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$2.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 a=0,i=1,s=0;for(this[t]=255&r;++a>0)-s&255;return t+e},Buffer$2.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 a=e-1,i=1,s=0;for(this[t+a]=255&r;--a>=0&&(i*=256);)r<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(r/i>>0)-s&255;return t+e},Buffer$2.prototype.writeInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,127,-128),Buffer$2.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),r<0&&(r=255+r+1),this[t]=255&r,t+1},Buffer$2.prototype.writeInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer$2.prototype.writeInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer$2.prototype.writeInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,2147483647,-2147483648),Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE=function(r,t,e){return writeFloat(this,r,t,!0,e)},Buffer$2.prototype.writeFloatBE=function(r,t,e){return writeFloat(this,r,t,!1,e)},Buffer$2.prototype.writeDoubleLE=function(r,t,e){return writeDouble(this,r,t,!0,e)},Buffer$2.prototype.writeDoubleBE=function(r,t,e){return writeDouble(this,r,t,!1,e)},Buffer$2.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(a<1e3||!Buffer$2.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,e=void 0===e?this.length:e>>>0,r||(r=0),"number"==typeof r)for(a=t;a55295&&e<57344){if(!o){if(e>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===n){(t-=3)>-1&&a.push(239,191,189);continue}o=e;continue}if(e<56320){(t-=3)>-1&&a.push(239,191,189),o=e;continue}e=65536+(o-55296<<10|e-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,e<128){if((t-=1)<0)break;a.push(e)}else if(e<2048){if((t-=2)<0)break;a.push(e>>6|192,63&e|128)}else if(e<65536){if((t-=3)<0)break;a.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;a.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return a}function asciiToBytes(r){for(var t=[],e=0;e>8,o=e%256,a.push(o),a.push(n);return a}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$1(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$1(r)?r:new Buffer$2.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$2.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),a=[];e.contract&&e.contract[t]&&e.contract[t].path&&a.push(e.contract[t].path),a.push(path.join(n,t,o,[INDEX_KEY,EXT].join(DOT))),a.push(path.join(n,t,[o,EXT].join(DOT)));for(var i=a.length,s=0;so?0:o+t),(e=e>o?o:e)<0&&(e+=o),o=t>e?0:e-t>>>0,t>>>=0;for(var a=Array(o);++n=n?r:baseSlice(r,t,e)}function baseFindIndex(r,t,e,n){for(var o=r.length,a=e+(n?1:-1);n?a--:++a-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}function listCacheClear(){this.__data__=[],this.size=0}function eq(r,t){return r===t||r!=r&&t!=t}function assocIndexOf(r,t){for(var e=r.length;e--;)if(eq(r[e][0],t))return e;return-1}var arrayProto=Array.prototype,splice=arrayProto.splice;function listCacheDelete(r){var t=this.__data__,e=assocIndexOf(t,r);return!(e<0)&&(e==t.length-1?t.pop():splice.call(t,e,1),--this.size,!0)}function listCacheGet(r){var t=this.__data__,e=assocIndexOf(t,r);return e<0?void 0:t[e][1]}function listCacheHas(r){return assocIndexOf(this.__data__,r)>-1}function listCacheSet(r,t){var e=this.__data__,n=assocIndexOf(e,r);return n<0?(++this.size,e.push([r,t])):e[n][1]=t,this}function ListCache(r){var t=-1,e=null==r?0:r.length;for(this.clear();++t-1&&r%1==0&&r<=MAX_SAFE_INTEGER}function isArrayLike(r){return null!=r&&isLength(r.length)&&!isFunction(r)}function isArrayLikeObject(r){return isObjectLike(r)&&isArrayLike(r)}function stubFalse(){return!1}var freeExports$1="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule$1=freeExports$1&&"object"==typeof module&&module&&!module.nodeType&&module,moduleExports$1=freeModule$1&&freeModule$1.exports===freeExports$1,Buffer$1=moduleExports$1?root.Buffer:void 0,nativeIsBuffer=Buffer$1?Buffer$1.isBuffer:void 0,isBuffer=nativeIsBuffer||stubFalse,argsTag$1="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",funcTag$1="[object Function]",mapTag="[object Map]",numberTag="[object Number]",objectTag$1="[object Object]",regexpTag="[object RegExp]",setTag="[object Set]",stringTag$1="[object String]",weakMapTag="[object WeakMap]",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]",typedArrayTags={};function baseIsTypedArray(r){return isObjectLike(r)&&isLength(r.length)&&!!typedArrayTags[baseGetTag(r)]}function baseUnary(r){return function(t){return r(t)}}typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag$1]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag$1]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag$1]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag$1]=typedArrayTags[weakMapTag]=!1;var freeExports$2="object"==typeof exports&&exports&&!exports.nodeType&&exports,freeModule$2=freeExports$2&&"object"==typeof module&&module&&!module.nodeType&&module,moduleExports$2=freeModule$2&&freeModule$2.exports===freeExports$2,freeProcess=moduleExports$2&&freeGlobal.process,nodeUtil=function(){try{var r=freeModule$2&&freeModule$2.require&&freeModule$2.require("util").types;return r||freeProcess&&freeProcess.binding&&freeProcess.binding("util")}catch(r){}}(),nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray,isTypedArray=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;function safeGet(r,t){if(("constructor"!==t||"function"!=typeof r[t])&&"__proto__"!=t)return r[t]}var objectProto$8=Object.prototype,hasOwnProperty$6=objectProto$8.hasOwnProperty;function assignValue(r,t,e){var n=r[t];hasOwnProperty$6.call(r,t)&&eq(n,e)&&(void 0!==e||t in r)||baseAssignValue(r,t,e)}function copyObject(r,t,e,n){var o=!e;e||(e={});for(var a=-1,i=t.length;++a-1&&r%1==0&&r0){if(++t>=HOT_COUNT)return arguments[0]}else t=0;return r.apply(void 0,arguments)}}var setToString=shortOut(baseSetToString);function baseRest(r,t){return setToString(overRest(r,t,identity),r+"")}function isIterateeCall(r,t,e){if(!isObject(e))return!1;var n=typeof t;return!!("number"==n?isArrayLike(e)&&isIndex(t,e.length):"string"==n&&t in e)&&eq(e[t],r)}function createAssigner(r){return baseRest((function(t,e){var n=-1,o=e.length,a=o>1?e[o-1]:void 0,i=o>2?e[2]:void 0;for(a=r.length>3&&"function"==typeof a?(o--,a):void 0,i&&isIterateeCall(e[0],e[1],i)&&(a=o<3?void 0:a,o=1),t=Object(t);++n0;)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,t){return void 0===t&&(t=!1),r.reduce((function(r,e){return r.then((function(r){return e.then((function(e){return!1===t?r.concat([e]):merge(r,e)}))}))}),Promise.resolve(!1===t?[]:isPlainObject(t)?t:{}))}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 inArray=function(r,t){return!!r.filter((function(r){return r===t})).length},parse=function(r){try{return JSON.parse(r)}catch(t){return r}},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},toJson=function(r){return"string"==typeof r?parse(r):JSON.parse(JSON.stringify(r))},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({__proto__:null,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,a=t.message||NO_ERROR_MSG,i=t.detail||t;if(o&&errors[o])throw new errors[e](a,i);throw new JsonqlError$1(a,i)}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({__proto__:null,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={},a=0;for(var i in e){var s=e[i],u=s.namespace;u&&(o[u]||(++a,o[u]={}),o[u][i]=s,n||s.public&&(n=u))}return{size:a,nspSet:o,publicNamespace:n}}function getNamespaceInOrder(r,t){var e=[];for(var n in r)n===t?e[1]=n:e[0]=n;return e}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 a={};if(a[PAYLOAD_PARAM_NAME]=t,a[CONDITION_PARAM_NAME]=e,!0===n)return a;if(isString(r))return(o={})[r]=a,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))},isJsonqlErrorObj=function(r){return!!["detail","className"].filter((function(t){return isKeyInObject(r,t)})).length&&["className","message","statusCode"].filter((function(t){return isKeyInObject(r,t)})).map((function(t){var e;return(e={})[t]="object"==typeof r[t]?r[t].toString():r[t],e})).reduce(merge,{detail:r.toString()})},packError=function(r,t,e,n){var o;void 0===t&&(t="JsonqlError"),void 0===e&&(e=0),void 0===n&&(n="");var a={detail:r,className:t,statusCode:e,message:n};return JSON.stringify(((o={})[ERROR_KEY]=isJsonqlErrorObj(r)||a,o))},resultHandler=function(r){return isKeyInObject(r,DATA_KEY)&&!isKeyInObject(r,ERROR_KEY)?r[DATA_KEY]:r},isContract=checkIsContract,VERSION="0.7.5",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");a="="===r[s-2]?2:"="===r[s-1]?1:0,i=new Arr(3*s/4-a),n=a>0?s-4:s;var u=0;for(t=0,e=0;t>16&255,i[u++]=o>>8&255,i[u++]=255&o;return 2===a?(o=revLookup[r.charCodeAt(t)]<<2|revLookup[r.charCodeAt(t+1)]>>4,i[u++]=255&o):1===a&&(o=revLookup[r.charCodeAt(t)]<<10|revLookup[r.charCodeAt(t+1)]<<4|revLookup[r.charCodeAt(t+2)]>>2,i[u++]=o>>8&255,i[u++]=255&o),i}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=[],a=t;as?s:i+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+="="),a.push(o),a.join("")}function read(r,t,e,n,o){var a,i,s=8*o-n-1,u=(1<>1,c=-7,l=e?o-1:0,p=e?-1:1,h=r[t+l];for(l+=p,a=h&(1<<-c)-1,h>>=-c,c+=s;c>0;a=256*a+r[t+l],l+=p,c-=8);for(i=a&(1<<-c)-1,a>>=-c,c+=n;c>0;i=256*i+r[t+l],l+=p,c-=8);if(0===a)a=1-f;else{if(a===u)return i?NaN:1/0*(h?-1:1);i+=Math.pow(2,n),a-=f}return(h?-1:1)*i*Math.pow(2,a-n)}function write(r,t,e,n,o,a){var i,s,u,f=8*a-o-1,c=(1<>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=n?0:a-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,i=c):(i=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-i))<1&&(i--,u*=2),(t+=i+l>=1?p/u:p*Math.pow(2,1-l))*u>=2&&(i++,u/=2),i+l>=c?(s=0,i=c):i+l>=1?(s=(t*u-1)*Math.pow(2,o),i+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,o),i=0));o>=8;r[e+h]=255&s,h+=g,s/=256,o-=8);for(i=i<0;r[e+h]=255&i,h+=g,i/=256,f-=8);r[e+h-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$2.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$2.from(t,n)),internalIsBuffer(t))return 0===t.length?-1:arrayIndexOf(r,t,e,n,o);if("number"==typeof t)return t&=255,Buffer$2.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 a,i=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;i=2,s/=2,u/=2,e/=2}function f(r,t){return 1===i?r[t]:r.readUInt16BE(t*i)}if(o){var c=-1;for(a=e;as&&(e=s-u),a=e;a>=0;a--){for(var l=!0,p=0;po&&(n=o):n=o;var a=t.length;if(a%2!=0)throw new TypeError("Invalid hex string");n>a/2&&(n=a/2);for(var i=0;i239?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&(a=r[o+1]))&&(u=(31&f)<<6|63&a)>127&&(c=u);break;case 3:a=r[o+1],i=r[o+2],128==(192&a)&&128==(192&i)&&(u=(15&f)<<12|(63&a)<<6|63&i)>2047&&(u<55296||u>57343)&&(c=u);break;case 4:a=r[o+1],i=r[o+2],s=r[o+3],128==(192&a)&&128==(192&i)&&128==(192&s)&&(u=(15&f)<<18|(63&a)<<12|(63&i)<<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$2.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer$2.poolSize=8192,Buffer$2._augment=function(r){return r.__proto__=Buffer$2.prototype,r},Buffer$2.from=function(r,t,e){return from(null,r,t,e)},Buffer$2.TYPED_ARRAY_SUPPORT&&(Buffer$2.prototype.__proto__=Uint8Array.prototype,Buffer$2.__proto__=Uint8Array),Buffer$2.alloc=function(r,t,e){return alloc(null,r,t,e)},Buffer$2.allocUnsafe=function(r){return allocUnsafe$1(null,r)},Buffer$2.allocUnsafeSlow=function(r){return allocUnsafe$1(null,r)},Buffer$2.isBuffer=isBuffer$1,Buffer$2.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,a=Math.min(e,n);o0&&(r=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(r+=" ... ")),""},Buffer$2.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 a=(o>>>=0)-(n>>>=0),i=(e>>>=0)-(t>>>=0),s=Math.min(a,i),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 a=!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(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(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="",a=t;ae)throw new RangeError("Trying to access beyond buffer length")}function checkInt(r,t,e,n,o,a){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,a=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,a=Math.min(r.length-e,4);o>>8*(n?o:3-o)&255}function checkIEEE754(r,t,e,n,o,a){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$2.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$2.prototype.readUInt8=function(r,t){return t||checkOffset(r,1,this.length),this[r]},Buffer$2.prototype.readUInt16LE=function(r,t){return t||checkOffset(r,2,this.length),this[r]|this[r+1]<<8},Buffer$2.prototype.readUInt16BE=function(r,t){return t||checkOffset(r,2,this.length),this[r]<<8|this[r+1]},Buffer$2.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$2.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$2.prototype.readIntLE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=this[r],o=1,a=0;++a=(o*=128)&&(n-=Math.pow(2,8*t)),n},Buffer$2.prototype.readIntBE=function(r,t,e){r|=0,t|=0,e||checkOffset(r,t,this.length);for(var n=t,o=1,a=this[r+--n];n>0&&(o*=256);)a+=this[r+--n]*o;return a>=(o*=128)&&(a-=Math.pow(2,8*t)),a},Buffer$2.prototype.readInt8=function(r,t){return t||checkOffset(r,1,this.length),128&this[r]?-1*(255-this[r]+1):this[r]},Buffer$2.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$2.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$2.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$2.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$2.prototype.readFloatLE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!0,23,4)},Buffer$2.prototype.readFloatBE=function(r,t){return t||checkOffset(r,4,this.length),read(this,r,!1,23,4)},Buffer$2.prototype.readDoubleLE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!0,52,8)},Buffer$2.prototype.readDoubleBE=function(r,t){return t||checkOffset(r,8,this.length),read(this,r,!1,52,8)},Buffer$2.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,a=0;for(this[t]=255&r;++a=0&&(a*=256);)this[t+o]=r/a&255;return t+e},Buffer$2.prototype.writeUInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,255,0),Buffer$2.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),this[t]=255&r,t+1},Buffer$2.prototype.writeUInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer$2.prototype.writeUInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer$2.prototype.writeUInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer$2.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$2.prototype.writeUInt32BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,4294967295,0),Buffer$2.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$2.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 a=0,i=1,s=0;for(this[t]=255&r;++a>0)-s&255;return t+e},Buffer$2.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 a=e-1,i=1,s=0;for(this[t+a]=255&r;--a>=0&&(i*=256);)r<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(r/i>>0)-s&255;return t+e},Buffer$2.prototype.writeInt8=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,1,127,-128),Buffer$2.TYPED_ARRAY_SUPPORT||(r=Math.floor(r)),r<0&&(r=255+r+1),this[t]=255&r,t+1},Buffer$2.prototype.writeInt16LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=255&r,this[t+1]=r>>>8):objectWriteUInt16(this,r,t,!0),t+2},Buffer$2.prototype.writeInt16BE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[t]=r>>>8,this[t+1]=255&r):objectWriteUInt16(this,r,t,!1),t+2},Buffer$2.prototype.writeInt32LE=function(r,t,e){return r=+r,t|=0,e||checkInt(this,r,t,4,2147483647,-2147483648),Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE=function(r,t,e){return writeFloat(this,r,t,!0,e)},Buffer$2.prototype.writeFloatBE=function(r,t,e){return writeFloat(this,r,t,!1,e)},Buffer$2.prototype.writeDoubleLE=function(r,t,e){return writeDouble(this,r,t,!0,e)},Buffer$2.prototype.writeDoubleBE=function(r,t,e){return writeDouble(this,r,t,!1,e)},Buffer$2.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(a<1e3||!Buffer$2.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,e=void 0===e?this.length:e>>>0,r||(r=0),"number"==typeof r)for(a=t;a55295&&e<57344){if(!o){if(e>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===n){(t-=3)>-1&&a.push(239,191,189);continue}o=e;continue}if(e<56320){(t-=3)>-1&&a.push(239,191,189),o=e;continue}e=65536+(o-55296<<10|e-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,e<128){if((t-=1)<0)break;a.push(e)}else if(e<2048){if((t-=2)<0)break;a.push(e>>6|192,63&e|128)}else if(e<65536){if((t-=3)<0)break;a.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;a.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return a}function asciiToBytes(r){for(var t=[],e=0;e>8,o=e%256,a.push(o),a.push(n);return a}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$1(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$1(r)?r:new Buffer$2.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$2.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),a=[];e.contract&&e.contract[t]&&e.contract[t].path&&a.push(e.contract[t].path),a.push(path.join(n,t,o,[INDEX_KEY,EXT].join(DOT))),a.push(path.join(n,t,[o,EXT].join(DOT)));for(var i=a.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":"+l4BAAAA,kvPCAA"} \ No newline at end of file +{"version":3,"file":"main.js","sources":["node_modules/jsonql-errors/src/get-error-name-by-instance.js","node_modules/buffer-es6/isArray.js"],"sourcesContent":["const UNKNOWN_ERROR = 'unknown'\n\n/**\n * @param {array} errs list of errors to compare from\n * @param {object} e the error captured\n * @return {array} filtered with name as value\n */\nfunction mapErrToName(errs, e) {\n return errs.filter(err => 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":"iw4BAAAA,yrQCAA"} \ No newline at end of file diff --git a/packages/utils/module.js b/packages/utils/module.js index 2894a0a880aa45e6266a167607341a4d006651ad..634bad55e0ec60924fd2b84b569f983c1a5bd550 100644 --- a/packages/utils/module.js +++ b/packages/utils/module.js @@ -6,6 +6,7 @@ import { checkIsContract, extractSocketPart, groupByNamespace, + getNamespaceInOrder, extractArgsFromPayload, extractParamsFromContract } from './src/contract' @@ -20,7 +21,8 @@ import { cacheBurstUrl, dasherize, getConfigValue, - isNotEmpty + isNotEmpty, + toJson } from './src/generic' import { toPayload, @@ -39,7 +41,8 @@ import { getCallMethod, packResult, packError, - resultHandler + resultHandler, + isJsonqlErrorObj } from './src/results' // alias @@ -51,6 +54,7 @@ export { packResult, packError, resultHandler, + isJsonqlErrorObj, // chain-fns chainFns, chainPromises, @@ -60,6 +64,7 @@ export { checkIsContract, extractSocketPart, groupByNamespace, + getNamespaceInOrder, isContract, // alias // generic inArray, @@ -72,6 +77,7 @@ export { cacheBurstUrl, getConfigValue, isNotEmpty, + toJson, // params-api toPayload, formatPayload, diff --git a/packages/utils/package.json b/packages/utils/package.json index 4a3e29e7558f32ebff389dbaee599a2fcc86ffb6..404c0f70160176da4251cb2ff95f3801dea70736 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,17 +1,17 @@ { "name": "jsonql-utils", - "version": "0.6.12", + "version": "0.7.5", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "index.js", "browser": "browser.js", "files": [ - "main.js", - "index.js", - "module.js", + "src", "browser.js", "debug.js", - "src" + "index.js", + "main.js", + "module.js" ], "scripts": { "test": "ava --verbose", @@ -64,12 +64,12 @@ "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.21.3", - "rollup-plugin-alias": "^2.0.0", + "rollup": "^1.23.1", + "rollup-plugin-alias": "^2.0.1", "rollup-plugin-analyzer": "^3.2.1", "rollup-plugin-async": "^1.2.0", "rollup-plugin-buble": "^0.19.8", diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 5d3b22d0fa2e163c06e0a6449fc47221d01a079a..90cc6cd73dbafec9bc1e34c21295355dabaf4442 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -76,6 +76,27 @@ export function groupByNamespace(contract, fallback = false) { return { size, nspSet, publicNamespace } } +/** + * @NOTE ported from jsonql-ws-client + * Got to make sure the connection order otherwise + * it will hang + * @param {object} nspSet contract + * @param {string} publicNamespace like the name said + * @return {array} namespaces in order + */ +export function getNamespaceInOrder(nspSet, publicNamespace) { + let names = []; // need to make sure the order! + for (let namespace in nspSet) { + if (namespace === publicNamespace) { + names[1] = namespace; + } else { + names[0] = namespace; + } + } + return names; +} + + /** * 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 088be6e444e983ebec12c4528d99072f9099707a..0b28f01d0c416caa1e251c3f9914caaa39cf3f78 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -12,6 +12,16 @@ export const inArray = (arr, value) => !!arr.filter(a => a === value).length; // quick and dirty to turn non array to array export const toArray = (arg) => isArray(arg) ? arg : [arg]; + +const parse = function(n) { + try { + return JSON.parse(n) + } catch(e) { + return n; + } +} + + /** * @param {object} obj for search * @param {string} key target @@ -87,6 +97,18 @@ export const getConfigValue = (name, obj) => ( obj && isPlainObject(obj) ? ( (name in obj) ? obj[name] : undefined ) : undefined ) +/** + * small util to make sure the return value is valid JSON object + * @param {*} n input + * @return {object} correct JSON object + */ +export const toJson = (n) => { + if (typeof n === 'string') { + return parse(n) + } + return JSON.parse(JSON.stringify(n)) +} + /** * Check several parameter that there is something in the param * @param {*} param input diff --git a/packages/utils/src/results.js b/packages/utils/src/results.js index ee6f385c0df9111f83c035b9424b76e739fe1933..d57bc1d4138beab824c1463dde71293b1f318afc 100644 --- a/packages/utils/src/results.js +++ b/packages/utils/src/results.js @@ -13,6 +13,7 @@ import { EXT } from 'jsonql-constants' import { isKeyInObject } from './generic' +import { merge } from './lodash' /** * getting what is calling after the above check * @param {string} method of call @@ -39,6 +40,27 @@ export const packResult = function(result) { return JSON.stringify({ [DATA_KEY]: result }) } +/** + * Check if the error object contain out custom key + * @param {*} e object + * @return {boolean} true + */ +export const isJsonqlErrorObj = e => { + const searchFields = ['detail', 'className'] + const test = !!searchFields.filter(field => isKeyInObject(e, field)).length + if (test) { + return ['className', 'message', 'statusCode'] + .filter(field => isKeyInObject(e, field)) + .map(field => ( + { + [field]: typeof e[field] === 'object' ? e[field].toString() : e[field] + } + )) + .reduce(merge, {detail: e.toString()}) // can only get as much as possible + } + return false; +} + /** * wrapper method - the output is trying to match up the structure of the Error sub class * @param {mixed} detail of fn error @@ -46,9 +68,12 @@ export const packResult = function(result) { * @param {number} [statusCode=500] the original error code * @return {string} stringify error */ -export const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { +export const packError = function(detail, className = 'JsonqlError', statusCode = 0, message = '') { + let errorObj = { detail, className, statusCode, message } + // we need to check the detail object to see if it has detail, className and message + // if it has then we should merge the object instead return JSON.stringify({ - [ERROR_KEY]: { detail, className, statusCode, message } + [ERROR_KEY]: isJsonqlErrorObj(detail) || errorObj }) } diff --git a/packages/ws-client/README.md b/packages/ws-client/README.md index 08154dc73dae37a28ac7b4745701baa7a3345640..1155456f421379f303eeb729133f0a5187d6b936 100644 --- a/packages/ws-client/README.md +++ b/packages/ws-client/README.md @@ -1,10 +1,16 @@ # jsonql-ws-client -**THIS PACKAGE IS NOW DEPRECATED** +This is for WebSocket client, all the core functionality moved to the jsonql-ws-base +for re-use and further develop other client / servers. + +This is mainly for use within the node client as a MQTT like interface. And this is more intend +to use in combination with the [jsonql-node-client](https://npmjs.com/package/jsonql-node-client) + +## Others We have break up all the jsonql socket client / server in several modules -- @jsonql/ws for WebSocket client / server +- ~~@jsonql/ws for WebSocket client / server~~ We keep the [jsonql-ws-server](https://npmjs.com/package/jsonql-ws-server) - @jsonql/socketio for Socket.io client / server - @jsonql/primus for Primus client / server diff --git a/packages/ws-client/package.json b/packages/ws-client/package.json index 18f1ec01155a26dd1eca5e49334ec1f38f331cf5..56cac0e739ee9f37c53944c69012bcc1137be330 100755 --- a/packages/ws-client/package.json +++ b/packages/ws-client/package.json @@ -1,7 +1,7 @@ { "name": "jsonql-ws-client", "version": "1.0.0", - "description": "This is the web socket client helper library", + "description": "This is the Web Socket client for Node and Browser", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-ws-client.js", @@ -12,9 +12,8 @@ "main.js" ], "scripts": { - "deprecated": "npm deprecate jsonql-ws-client \"This module is no longer maintain, please move to the new @jsonql/socketio or @jsonql/ws modules\" and check https://jsonql.js.org for up to date version", - "test": "DEBUG=jsonql-ws* ava --verbose", - "_prepare_": "npm run build", + "test": "ava --verbose", + "prepare": "npm run build && npm run test", "build": "npm run build:browser && npm run build:cjs", "build:browser": "NODE_ENV=umd rollup -c", "build:cjs": "NODE_ENV=cjs rollup -c ./rollup.config.node.js", @@ -53,15 +52,15 @@ }, "dependencies": { "esm": "^3.2.25", - "jsonql-constants": "^1.8.2", - "jsonql-errors": "^1.1.2", - "jsonql-jwt": "^1.3.0", - "jsonql-params-validator": "^1.4.6", - "jsonql-utils": "^0.4.3", + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", + "jsonql-jwt": "^1.3.2", + "jsonql-params-validator": "^1.4.11", + "jsonql-utils": "^0.7.4", "nb-event-service": "^1.8.3" }, "devDependencies": { - "ava": "^2.3.0", + "ava": "^2.4.0", "fs-extra": "^8.1.0", "kefir": "^3.8.6" }, diff --git a/packages/ws-client/src/client-event-handler.js b/packages/ws-client/src/core/client-event-handler.js similarity index 100% rename from packages/ws-client/src/client-event-handler.js rename to packages/ws-client/src/core/client-event-handler.js diff --git a/packages/ws-client/src/utils/client-generator.js b/packages/ws-client/src/core/client-generator.js similarity index 100% rename from packages/ws-client/src/utils/client-generator.js rename to packages/ws-client/src/core/client-generator.js diff --git a/packages/ws-client/src/utils/create-nsp-client.js b/packages/ws-client/src/core/create-nsp-client.js similarity index 100% rename from packages/ws-client/src/utils/create-nsp-client.js rename to packages/ws-client/src/core/create-nsp-client.js diff --git a/packages/ws-client/src/create-socket-client.js b/packages/ws-client/src/core/create-socket-client.js similarity index 100% rename from packages/ws-client/src/create-socket-client.js rename to packages/ws-client/src/core/create-socket-client.js diff --git a/packages/ws-client/src/generator.js b/packages/ws-client/src/core/generator.js similarity index 100% rename from packages/ws-client/src/generator.js rename to packages/ws-client/src/core/generator.js diff --git a/packages/ws-client/src/utils/trigger-namespaces-on-error.js b/packages/ws-client/src/core/trigger-namespaces-on-error.js similarity index 100% rename from packages/ws-client/src/utils/trigger-namespaces-on-error.js rename to packages/ws-client/src/core/trigger-namespaces-on-error.js diff --git a/packages/ws-client/src/index.js b/packages/ws-client/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a520ff3d6e7ce7a45c8e053bdac6f891c37a2ae4 --- /dev/null +++ b/packages/ws-client/src/index.js @@ -0,0 +1,45 @@ +// This was in the main.js - just put it here for now + +import createSocketClient from './create-socket-client' +import generator from './generator' + +import { checkOptions, ee, processContract } from './utils' + +/** + * The main interface to create the wsClient for use + * @param {function} clientGenerator this is an internal way to generate node or browser client + * @return {function} wsClient + * @public + */ +export default function main(clientGenerator) { + /** + * @param {object} config configuration + * @param {object} [eventEmitter=false] this will be the bridge between clients + * @return {object} wsClient + */ + const wsClient = (config, eventEmitter = false) => { + return checkOptions(config) + .then(opts => ({ + opts, + nspMap: processContract(opts), + ee: eventEmitter || new ee() + }) + ) + .then(clientGenerator) + .then( + ({ opts, nspMap, ee }) => createSocketClient(opts, nspMap, ee) + ) + .then( + ({ opts, nspMap, ee }) => generator(opts, nspMap, ee) + ) + .catch(err => { + console.error('jsonql-ws-client init error', err) + }) + } + // use the Object.addProperty trick + Object.defineProperty(wsClient, 'CLIENT_TYPE_INFO', { + value: '__PLACEHOLDER__', + writable: false + }) + return wsClient; +} diff --git a/packages/ws-client/src/main.js b/packages/ws-client/src/main.js index ae6ae9129b67f5561a9ec7bcb7c67430ca63edfe..14059c479e0b27dff62fabe825fa8348168cd75a 100644 --- a/packages/ws-client/src/main.js +++ b/packages/ws-client/src/main.js @@ -1,45 +1,13 @@ -// main api to get the ws-client - -import createSocketClient from './create-socket-client' -import generator from './generator' - -import { checkOptions, ee, processContract } from './utils' +// the top level API +// The goal is to create a generic method that will able to handle +// any kind of clients /** - * The main interface to create the wsClient for use - * @param {function} clientGenerator this is an internal way to generate node or browser client - * @return {function} wsClient - * @public + * @param {object} opts configuration @NOTE we expect the contract to be part of the options + * @param {object} socketClient we normalize the auth and non auth client from now on + * @return {object} the wsClient instance with all the available API */ -export default function main(clientGenerator) { - /** - * @param {object} config configuration - * @param {object} [eventEmitter=false] this will be the bridge between clients - * @return {object} wsClient - */ - const wsClient = (config, eventEmitter = false) => { - return checkOptions(config) - .then(opts => ({ - opts, - nspMap: processContract(opts), - ee: eventEmitter || new ee() - }) - ) - .then(clientGenerator) - .then( - ({ opts, nspMap, ee }) => createSocketClient(opts, nspMap, ee) - ) - .then( - ({ opts, nspMap, ee }) => generator(opts, nspMap, ee) - ) - .catch(err => { - console.error('jsonql-ws-client init error', err) - }) - } - // use the Object.addProperty trick - Object.defineProperty(wsClient, 'CLIENT_TYPE_INFO', { - value: '__PLACEHOLDER__', - writable: false - }) - return wsClient; +export default function wsClient(opts, socketClient) { + + } diff --git a/packages/ws-client/src/utils/constants.js b/packages/ws-client/src/options/constants.js similarity index 100% rename from packages/ws-client/src/utils/constants.js rename to packages/ws-client/src/options/constants.js diff --git a/packages/ws-client/src/utils/check-options.js b/packages/ws-client/src/options/index.js similarity index 80% rename from packages/ws-client/src/utils/check-options.js rename to packages/ws-client/src/options/index.js index 045a2a8858f0f278d567c86124cf5cc9e0242056..39d72a2cb822dfd9d578dc5ea2ceb2c4a9aed0fb 100644 --- a/packages/ws-client/src/utils/check-options.js +++ b/packages/ws-client/src/options/index.js @@ -1,6 +1,14 @@ // create options -import { createConfig, checkConfigAsync, isContract, isNotEmpty } from 'jsonql-params-validator' -import { JsonqlValidationError, JsonqlCheckerError } from 'jsonql-errors' +import { + createConfig, + checkConfigAsync, + isContract, + isNotEmpty +} from 'jsonql-params-validator' +import { + JsonqlValidationError, + JsonqlCheckerError +} from 'jsonql-errors' import { STRING_TYPE, BOOLEAN_TYPE, @@ -11,21 +19,12 @@ import { ISSUER_NAME, LOGOUT_NAME } from 'jsonql-constants' +// this should be remove - we have to make it generic import { SOCKET_IO, WS, AVAILABLE_SERVERS } from './constants' -import getDebug from './get-debug' +import { getDebug } from '../utils' const debug = getDebug('check-options') -const fixWss = (url, serverType) => { - // ws only allow ws:// path - if (serverType===WS) { - return url.replace('http://', 'ws://') - } - return url; -} -const getHostName = () => ( - [window.location.protocol, window.location.host].join('//') -) const constProps = { // this will be the switcher! diff --git a/packages/ws-client/src/utils/get-debug.js b/packages/ws-client/src/utils/get-debug.js index d6615dcf8d3f47f655499a91e4fa3b6192440abb..7ef63c8b772fe1ca37abc8639339fa8283f13eaa 100644 --- a/packages/ws-client/src/utils/get-debug.js +++ b/packages/ws-client/src/utils/get-debug.js @@ -1,21 +1,32 @@ -// not using the jsonql-utils version -import debug from 'debug' +const BASE_NAME = 'jsonql-ws-client' /** * Try to normalize it to use between browser and node * @param {string} name for the debug output * @return {function} debug */ -const getDebug = name => { - if (debug) { - return debug('jsonql-ws-client').extend(name) +const getDebug = (name) => { + try { + if (window.debug) { // the global browser object + return window.debug(BASE_NAME).extend(name) + } + } catch(e) { + // ignore this } + try { + if (global.debug) { + return global.debug(BASE_NAME).extend(name) + } + } catch(e) { + // ignore this + } + // just a stock one return (...args) => { - console.info.apply(null, [name].concat(args)); + console.info.apply(null, [BASE_NAME, name].concat(args)) } } try { if (window && window.localStorage) { - localStorage.setItem('DEBUG', 'jsonql-ws-client*'); + localStorage.setItem('DEBUG', 'jsonql-ws-client*') } } catch(e) {} // export it diff --git a/packages/ws-client/src/utils/get-namespace-in-order.js b/packages/ws-client/src/utils/get-namespace-in-order.js deleted file mode 100644 index 823a6256e2b7e2ab03210a1cda31fb10239a51be..0000000000000000000000000000000000000000 --- a/packages/ws-client/src/utils/get-namespace-in-order.js +++ /dev/null @@ -1,20 +0,0 @@ - - -/** - * Got to make sure the connection order otherwise - * it will hang - * @param {object} nspSet contract - * @param {string} publicNamespace like the name said - * @return {array} namespaces in order - */ -export default function getNamespaceInOrder(nspSet, publicNamespace) { - let names = []; // need to make sure the order! - for (let namespace in nspSet) { - if (namespace === publicNamespace) { - names[1] = namespace; - } else { - names[0] = namespace; - } - } - return names; -} diff --git a/packages/ws-client/src/utils/helpers.js b/packages/ws-client/src/utils/helpers.js new file mode 100644 index 0000000000000000000000000000000000000000..e0e1a6445f66174ad9093e617a9ff33501938c2a --- /dev/null +++ b/packages/ws-client/src/utils/helpers.js @@ -0,0 +1,66 @@ +// group all the small functions here +import { + QUERY_ARG_NAME, + JS_WS_SOCKET_IO_NAME +} from 'jsonql-constants' + +// we shouldn't do this anymore +export const fixWss = (url, serverType) => { + // ws only allow ws:// path + if (serverType === WS) { + return url.replace('http://', 'ws://') + } + return url; +} + +/** + * get a stock host name from browser + */ +export const getHostName = () => { + try { + return [window.location.protocol, window.location.host].join('//') + } catch(e) { + throw new JsonqlValidationError(e) + } +} + +/** + * Unbind the event + * @param {object} ee EventEmitter + * @param {string} namespace + * @return {void} + */ +export const clearMainEmitEvt = (ee, namespace) => { + let nsps = isArray(namespace) ? namespace : [namespace] + nsps.forEach(n => { + ee.$off(createEvt(n, constants.EMIT_EVT)) + }) +} + +/** + * @param {*} args arguments to send + *@return {object} formatted payload + */ +export const formatPayload = (args) => ( + { [QUERY_ARG_NAME]: args } +) + +/** + * @param {object} nsps namespace as key + * @param {string} type of server + */ +export const disconnect = (nsps, type = JS_WS_SOCKET_IO_NAME) => { + try { + // + const method = type === JS_WS_SOCKET_IO_NAME ? 'disconnect' : 'terminate'; + for (let namespace in nsps) { + let nsp = nsps[namespace] + if (nsp && nsp[method]) { + Reflect.apply(nsp[method], null, []) + } + } + } catch(e) { + // socket.io throw a this.destroy of undefined? + console.error('Disconnect call failed', e) + } +} diff --git a/packages/ws-client/src/utils/index.js b/packages/ws-client/src/utils/index.js index f412c93b632b34812a3eb1f515475fe52f5cf8a9..15017704c7e40128d1974f061dbcf36b8bae0e9f 100644 --- a/packages/ws-client/src/utils/index.js +++ b/packages/ws-client/src/utils/index.js @@ -1,5 +1,5 @@ // export the util methods -import { QUERY_ARG_NAME, JS_WS_SOCKET_IO_NAME } from 'jsonql-constants' + import getNamespaceInOrder from './get-namespace-in-order' import checkOptions from './check-options' import ee from './ee' @@ -8,48 +8,10 @@ import getDebug from './get-debug' import processContract from './process-contract' import { isArray } from 'jsonql-params-validator' -// moved to jsonql-utils +// moved to jsonql-utils import { toArray, createEvt } from 'jsonql-utils' -/** - * Unbind the event - * @param {object} ee EventEmitter - * @param {string} namespace - * @return {void} - */ -const clearMainEmitEvt = (ee, namespace) => { - let nsps = isArray(namespace) ? namespace : [namespace] - nsps.forEach(n => { - ee.$off(createEvt(n, constants.EMIT_EVT)) - }) -} - -/** - * @param {*} args arguments to send - *@return {object} formatted payload - */ -const formatPayload = (args) => ( - { [QUERY_ARG_NAME]: args } -) -/** - * @param {object} nsps namespace as key - * @param {string} type of server - */ -const disconnect = (nsps, type = JS_WS_SOCKET_IO_NAME) => { - try { - const method = type === JS_WS_SOCKET_IO_NAME ? 'disconnect' : 'terminate'; - for (let namespace in nsps) { - let nsp = nsps[namespace] - if (nsp && nsp[method]) { - Reflect.apply(nsp[method], null, []) - } - } - } catch(e) { - // socket.io throw a this.destroy of undefined? - console.error('disconnect', e) - } -} export { diff --git a/packages/ws-client/src/utils/process-contract.js b/packages/ws-client/src/utils/process-contract.js index 7ec6a8554d01e10caa714b6d0eebb0d4d0b0a4e7..43f6a1726d00f540599f7d4fd8c8883c0d61e3f1 100644 --- a/packages/ws-client/src/utils/process-contract.js +++ b/packages/ws-client/src/utils/process-contract.js @@ -1,10 +1,10 @@ // mapping the resolver to their respective nsp - -import { JSONQL_PATH } from 'jsonql-constants' -import { groupByNamespace } from 'jsonql-jwt' +import { JSONQL_PATH, NSP_SET, PUBLIC_NAMESPACE } from 'jsonql-constants' +import { groupByNamespace, extractSocketPart } from 'jsonql-utils' import { JsonqlResolverNotFoundError } from 'jsonql-errors' -import { MISSING_PROP_ERR } from './constants' +import { MISSING_PROP_ERR } from '../options/constants' + import getDebug from './get-debug' const debug = getDebug('process-contract') @@ -14,11 +14,9 @@ const debug = getDebug('process-contract') * @return {object} the target content */ const getResolverList = contract => { - if (contract) { - const { socket } = contract; - if (socket) { - return socket; - } + const result = extractSocketPart(contract) + if (result !== false) { + return result } throw new JsonqlResolverNotFoundError(MISSING_PROP_ERR) } @@ -34,8 +32,7 @@ export default function processContract(opts) { return groupByNamespace(contract) } return { - nspSet: { [JSONQL_PATH]: getResolverList(contract) }, - publicNamespace: JSONQL_PATH, - size: 1 // this prop is pretty meaningless now + [NSP_SET]: { [JSONQL_PATH]: getResolverList(contract) }, + [PUBLIC_NAMESPACE]: JSONQL_PATH } } diff --git a/packages/ws-server/client.js b/packages/ws-server/client.js new file mode 100644 index 0000000000000000000000000000000000000000..a5829264d5481985546181a433276dc7d621a037 --- /dev/null +++ b/packages/ws-server/client.js @@ -0,0 +1,13 @@ +// we also provide a node client here +const WebSocket = require('ws') +const { TOKEN_PARAM_NAME } = require('jsonql-constants') +/** + * Create a client with auth token + * @param {string} url start with ws:// @TODO check this? + * @param {string} [token = false] the jwt token + * @return {object} ws instance + */ +module.exports = function client(url, token = false) { + let uri = token ? `${url}?${TOKEN_PARAM_NAME}=${token}` : url; + return new WebSocket(uri) +} diff --git a/packages/ws-server/index.js b/packages/ws-server/index.js index 5889fa5d5fb064e97f2284dba56ab3d2c20842e6..a87d7ae351555856d1043a7c2597184f8068edae 100644 --- a/packages/ws-server/index.js +++ b/packages/ws-server/index.js @@ -1,7 +1,11 @@ // Not going to use the koa-socket-2 due to it's lack of support namespace // which is completely useless for us if there is no namespace -const { getServer, checkOptions, generator } = require('./lib') -const { getDebug } = require('./lib/share/helpers') +const { + checkOptions, + wsSetup, + wsCreateServer +} = require('./src') +const { getDebug } = require('./src/share/helpers') const debug = getDebug('main') /** * @param {object} config this is now diverse from the middleware setup @@ -13,18 +17,11 @@ const debug = getDebug('main') module.exports = function jsonqlWsServer(config, server) { // @TODO check the options return checkOptions(config) - .then(opts => ({ - wsServer: getServer(opts.serverType), - opts - }) - ) - .then( ({ opts, wsServer }) => { - // return is a key value pair object key is the namespace object is the io itself - const nspObj = wsServer(opts, server) - return [opts, nspObj] + .then(opts => { + const nspObj = wsCreateServer(opts, server) + return Reflect.apply(wsSetup, null, [opts, nspObj]) }) - .then( args => Reflect.apply(generator, null, args) ) .catch(err => { - console.error('Init jsonql ws server error', err) + console.error('Init jsonql WebSocket server error', err) }) } diff --git a/packages/ws-server/lib/generator.js b/packages/ws-server/lib/generator.js deleted file mode 100644 index 5e204c0d665187e38799b85d94e0f0eefeedb96e..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/generator.js +++ /dev/null @@ -1,28 +0,0 @@ -// this will take the contract json file -// search for the socket and use the enableAuth to determine how to -// attach each method into the nsp object -const { - SOCKET_IO, - WS, - SOCKET_NOT_DEFINE_ERR -} = require('./share/constants') -const { JsonqlError } = require('jsonql-errors') -const { socketIoSetup } = require('./socket-io') -const { wsSetup } = require('./ws') - -/** - * Here will add the methods found from contract add to the io object - * @param {object} opts configuration - * @param {object} nsp the ws server instance - * @return {void} nothing to return - */ -module.exports = function(opts, nsp) { - // the authentication run during the setup - switch (opts.serverType) { - case SOCKET_IO: - return socketIoSetup(opts, nsp) - case WS: - return wsSetup(opts, nsp) - } - throw new JsonqlError(SOCKET_NOT_DEFINE_ERR) -} diff --git a/packages/ws-server/lib/index.js b/packages/ws-server/lib/index.js deleted file mode 100644 index 07ac860d8e5d3789e5b2abd231c7ed13df58a155..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/index.js +++ /dev/null @@ -1,35 +0,0 @@ -// re-export here -const { socketIoCreateServer } = require('./socket-io') -const { wsCreateServer } = require('./ws') -const generator = require('./generator') -const { - SOCKET_IO, - WS, - SERVER_NOT_SUPPORT_ERR -} = require('./share/constants') -const checkOptions = require('./check-options') -const { getDebug } = require('./share/helpers') -const debug = getDebug('lib-index') - -/** - * @param {string} name of the server - * @return {function} for constructing the server - */ -const getServer = name => { - debug('getServer', name) - switch (name) { - case WS: - return wsCreateServer; - case SOCKET_IO: - return socketIoCreateServer; - default: - throw new Error(`${name} ${SERVER_NOT_SUPPORT_ERR}`) - } -} - -// re-export -module.exports = { - getServer, - checkOptions, - generator -}; diff --git a/packages/ws-server/lib/share/add-handler-property.js b/packages/ws-server/lib/share/add-handler-property.js deleted file mode 100644 index 44b11706cc46c2c6a45e5e60725a7d87cc769486..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/share/add-handler-property.js +++ /dev/null @@ -1,25 +0,0 @@ -// we should be using a generic method to add handler property -// at the moment the server only has a `send` method -// and there should be a onMessage method for them to received -// what the client send back instead of relying on them to -// construct listener using the raw socket object - -/** - * @param {function} fn the resolver - * @param {string} name the name of the property - * @param {function} setter for set - * @param {function} getter for get - * @param {object} [options={}] extra options for defineProperty - * @return {function} the resolver itself - */ -function addHandlerProperty(fn, name, setter, getter , options = {}) { - if (Object.getOwnPropertyDescriptor(fn, name) === undefined) { - Object.defineProperty(fn, name, Object.assign({ - set: setter, - get: getter - }, options)) - } - return fn; -} -// export -module.exports = addHandlerProperty; diff --git a/packages/ws-server/lib/share/add-ws-property.js b/packages/ws-server/lib/share/add-ws-property.js deleted file mode 100644 index 81b911302b94eec3d737351d74c867003093ba6a..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/share/add-ws-property.js +++ /dev/null @@ -1,19 +0,0 @@ - -/** - * this is a generic method that add the socket property - * to the resolver function for other use - * @param {function} fn the resolver - * @param {object} socket the socket.io socket or nsp - * @return {function} fn the resolver + new property from ctx - */ -const addWsProperty = (fn , socket) => { - if (Object.getOwnPropertyDescriptor(fn, 'socket') === undefined) { - Object.defineProperty(fn, 'socket', { - value: socket, - writeable: false - }) - } - return fn; -} -// export -module.exports = addWsProperty; diff --git a/packages/ws-server/lib/share/resolve-method.js b/packages/ws-server/lib/share/resolve-method.js deleted file mode 100644 index a6a1ad568045643d3aa95ca3f8d02424d622879f..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/share/resolve-method.js +++ /dev/null @@ -1,181 +0,0 @@ -// search for the resolver location -const fs = require('fs') -const { join } = require('path') -const { isUndefined } = require('lodash') -const { - JsonqlAuthorisationError, - JsonqlResolverNotFoundError, - JsonqlResolverAppError, - JsonqlValidationError, - JsonqlError, - finalCatch -} = require('jsonql-errors') -const { - SOCKET_NAME, - DEFAULT_RESOLVER_IMPORT_FILE_NAME, - MODULE_TYPE -} = require('jsonql-constants') -const { validateSync } = require('jsonql-params-validator') -const { provideUserdata } = require('jsonql-jwt') -const { dasherize } = require('./helpers') -// the addProperty methods -const socketIoAddProperty = require('../socket-io/add-property') -const wsAddProperty = require('../ws/add-property') - -const { SOCKET_IO, WS } = require('./constants') - -const debug = require('debug')('jsonql-ws-server:resolve-method') -/** - * @param {string} name resolverName - * @param {string} type resolverType - * @param {object} opts configuration - * @return {function} resolver 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') ) - const ctn = paths.length; - for (let i=0; i { - let _fn; - switch(serverType) { - case SOCKET_IO: - _fn = socketIoAddProperty(fn, resolverName, ws) - break; - case WS: - _fn = wsAddProperty(fn, resolverName, ws) - break; - default: - throw new JsonqlError(`No such serverType: ${serverType} for ${resolverName}`) - } - // group the provide userdata together - return isUndefined(userdata) ? _fn : provideUserdata(_fn, userdata) -} - -/** - * similiar to the one in Koa-middleware without the ctx - * @param {string} resolverName name to call - * @param {array} args arguments - * @param {object} params extracted params - * @param {object} opts for search later - * @param {object} userdata userdata - * @param {object} ws io for socket.io - * @param {object|boolean} userdata false when there is none userdata - * @return {mixed} depends on the contract - */ -const resolveMethod = function(resolverName, args, params, opts, ws, userdata) { - const fn = getResolver(resolverName, params, opts) - const tfn = addProperty(opts.serverType, fn, resolverName, ws, userdata) - try { - return Reflect.apply(tfn, null, args) - } catch(e) { - throw new JsonqlResolverAppError(resolverName, e) - } -} - -// we only need to export one method -module.exports = resolveMethod diff --git a/packages/ws-server/lib/ws/create-ws-reply.js b/packages/ws-server/lib/ws/create-ws-reply.js deleted file mode 100644 index 1b2b0ee43a82263bd88f4dbc7e51db529d746393..0000000000000000000000000000000000000000 --- a/packages/ws-server/lib/ws/create-ws-reply.js +++ /dev/null @@ -1,28 +0,0 @@ -// for some really really weird reason if I put this into the utils/helpers -// its unable to import into the module here -// since this is for ws only then we could just put in here instead -const { - WS_REPLY_TYPE, - WS_EVT_NAME, - WS_DATA_NAME -} = require('jsonql-constants') -// const debug = require('debug')('jsonql-ws-server:create-ws-reply'); -/** - * The ws doesn't have a acknowledge callback like socket.io - * so we have to DIY one for ws and other that doesn't have it - * @param {string} type of reply - * @param {string} resolverName which is replying - * @param {*} data payload - * @return {string} stringify json - */ -const createWsReply = (type, resolverName, data) => { - return JSON.stringify({ - data: { - [WS_REPLY_TYPE]: type, - [WS_EVT_NAME]: resolverName, - [WS_DATA_NAME]: data - } - }) -} - -module.exports = createWsReply diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index 369b5b0cfe9af6a8a6536e03fe76f79093ab9558..56d143a99f75152cd225546d740aeba61b7e0a6b 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -1,21 +1,19 @@ { "name": "jsonql-ws-server", - "version": "1.2.1", - "description": "Setup WebSocket / Socket.io server for the jsonql to run on the same host, automatic generate public / private channel using contract", + "version": "1.3.0", + "description": "Setup WebSocket server for the jsonql to run on the same host, automatic generate public / private channel using contract", "main": "index.js", "files": [ "index.js", - "lib" + "client.js", + "src" ], "scripts": { - "deprecated": "npm deprecate jsonql-ws-server \"This module is no longer maintain, please move to the new @jsonql/socketio or @jsonql/ws modules\"", - "test": "DEBUG=jsonql-ws-server* ava --verbose", + "test": "ava --verbose", "test:ws": "DEBUG=jsonql-ws-server* ava ./tests/ws-connect.test.js", + "test:error": "DEBUG=jsonql-ws-server* ava ./tests/ws-connect-error.test.js", "test:es6": "DEBUG=jsonql-ws-server* ava ./tests/ws-connect-es6.test.js", - "test:ws:jwt": "DEBUG=jsonql-ws-server* ava ./tests/ws-jwt-auth.test.js", - "test:io": "DEBUG=jsonql-ws-server* ava ./tests/socket-io.test.js", - "test:io:jwt": "DEBUG=jsonql-* ava ./tests/socket-io-handshake.test.js", - "test:io:auth": "DEBUG=jsonql-* ava ./tests/socket-io-roundtrip.test.js", + "test:jwt": "DEBUG=jsonql-ws-server* ava ./tests/ws-jwt-auth.test.js", "test:object": "DEBUG=jsonql-ws-server* ava --verbose ./tests/object.test.js", "contract": "node ./node_modules/jsonql-contract/cmd.js configFile ./tests/fixtures/contract-config.js", "test:browser": "DEBUG=jsonql* node ./tests/fixtures/browser-test-setup.js" @@ -30,23 +28,22 @@ "author": "Joel Chu ", "license": "MIT", "dependencies": { + "debug": "^4.1.1", "esm": "^3.2.25", "fs-extra": "^8.1.0", - "jsonql-constants": "^1.7.8", - "jsonql-errors": "^1.0.9", - "jsonql-jwt": "^1.2.1", - "jsonql-params-validator": "^1.4.3", - "lodash": "^4.17.11", - "socket.io": "^2.2.0", - "ws": "^7.0.1" + "jsonql-constants": "^1.8.3", + "jsonql-errors": "^1.1.3", + "jsonql-jwt": "^1.3.2", + "jsonql-params-validator": "^1.4.11", + "jsonql-resolver": "^0.9.4", + "jsonql-utils": "^0.7.4", + "lodash": "^4.17.15", + "ws": "^7.1.2" }, "devDependencies": { - "ava": "^2.1.0", - "debug": "^4.1.1", - "jsonql-contract": "^1.7.3", - "open": "^6.4.0", - "socket.io-client": "^2.2.0", - "socketio-jwt": "^4.5.0" + "ava": "^2.4.0", + "jsonql-contract": "^1.7.21", + "open": "^6.4.0" }, "ava": { "files": [ diff --git a/packages/ws-server/lib/check-options/index.js b/packages/ws-server/src/check-options/index.js similarity index 100% rename from packages/ws-server/lib/check-options/index.js rename to packages/ws-server/src/check-options/index.js diff --git a/packages/ws-server/lib/ws/add-property.js b/packages/ws-server/src/core/add-property.js similarity index 76% rename from packages/ws-server/lib/ws/add-property.js rename to packages/ws-server/src/core/add-property.js index 99b39b3ba03d2b2227ce91161f3326c3aa9e7bbd..fbbf2d7962a498327176fbf96fa1f74de3bbdc76 100644 --- a/packages/ws-server/lib/ws/add-property.js +++ b/packages/ws-server/src/core/add-property.js @@ -1,9 +1,8 @@ - -// const debug = require('debug')('jsonql-ws-server:ws-add-property'); +// add required properties to the resolver const createWsReply = require('./create-ws-reply') const { EMIT_REPLY_TYPE, SEND_MSG_PROP_NAME, MESSAGE_PROP_NAME } = require('jsonql-constants') -// const { JsonqlError } = require('jsonql-errors') -const addHandlerProperty = require('../share/add-handler-property') + +const { objDefineProps } = require('jsonql-utils') const { nil } = require('../share/helpers') /** @@ -14,7 +13,8 @@ const { nil } = require('../share/helpers') */ const addProperty = (fn, resolverName, ws) => { let resolver; - resolver = addHandlerProperty(fn, SEND_MSG_PROP_NAME, function(prop) { + + resolver = objDefineProps(fn, SEND_MSG_PROP_NAME, function(prop) { ws.send(createWsReply(EMIT_REPLY_TYPE, resolverName, prop)) }, nil) /* diff --git a/packages/ws-server/lib/ws/index.js b/packages/ws-server/src/core/index.js similarity index 100% rename from packages/ws-server/lib/ws/index.js rename to packages/ws-server/src/core/index.js diff --git a/packages/ws-server/src/core/verify-client.js b/packages/ws-server/src/core/verify-client.js new file mode 100644 index 0000000000000000000000000000000000000000..80334caceb4270ce7b3388c34e771caf504778be --- /dev/null +++ b/packages/ws-server/src/core/verify-client.js @@ -0,0 +1,59 @@ +// export the verifyClient at init time for a handshake authentication +const url = require('url') +const { TOKEN_PARAM_NAME } = require('jsonql-constants') +const { jwtDecode } = require('jsonql-jwt') +const debug = require('debug')('jsonql-jwt:ws:verify-client') + +/** + * What the name said + * @param {string} uri to decode + * @return {string} token or nothing means didn't find it + */ +function getTokenFromQuery(uri) { + const { query } = url.parse(uri) + const params = query.split('&') + return params.filter(param => ( + param.indexOf(TOKEN_PARAM_NAME) > -1 + )) + .reduce((f, n) => n ? n.split('=')[1] : f, false) +} + +/** + * provide the necessary param to create the verifyClient function + * @param {string|buffer} publicKey for decoding + * @param {object} [jwtOptions={}] optional pass to the jwtDecode + * @param {function|boolean} [failCallback=false] if the token is invalid + * @return {function} verifyClient method + */ +function createVerifyClient(publicKey, jwtOptions = {}, failCallback = false) { + const cb = failCallback === false ? msg => { + console.error('verifyClient error', msg) + } : failCallback; + /** + * pass this as part of the option to the WebSocket at init time + * @param {object} info we use the info.req.url to extract the token + * @param {function} done a callback to pass or fail the login + */ + return function verifyClient(info, done) { + let token = getTokenFromQuery(info.req.url) + if (token) { + try { + let payload = jwtDecode(token, publicKey, jwtOptions) + debug(`calling verifyClient`, payload) + if (!info.req.state) { + info.req.state = {}; + } + // passing this along to the next + info.req.state.userdata = payload; + return done(payload) + } catch(e) { + done(false) + cb(e) + } + } + cb('no token!') + done(false) + } +} + +module.exports = { createVerifyClient } diff --git a/packages/ws-server/lib/ws/ws-create-server.js b/packages/ws-server/src/core/ws-create-server.js similarity index 92% rename from packages/ws-server/lib/ws/ws-create-server.js rename to packages/ws-server/src/core/ws-create-server.js index e58a9c4d6f281709a22f12ae6b1ffb7d310212ae..476053176c62d15949a758ef52f3200762882678 100644 --- a/packages/ws-server/lib/ws/ws-create-server.js +++ b/packages/ws-server/src/core/ws-create-server.js @@ -1,12 +1,12 @@ // web socket server based on ws const url = require('url') const WebSocket = require('ws') -const { wsVerifyClient } = require('jsonql-jwt') +// need to move the method back here +const { createVerifyClient } = require('./verify-client') const { getNamespace, getDebug } = require('../share/helpers') const debug = getDebug('ws-setup') - /** * @param {array} namespace string * @param {object} config configuration @@ -16,7 +16,7 @@ const generateWss = (namespace, config) => { let verifyClient; if (config.enableAuth) { let key = config.secret ? config.secret : config.publicKey; - verifyClient = wsVerifyClient(key) + verifyClient = createVerifyClient(key) } return namespace.map((name, i) => { let c = { noServer: true }; @@ -61,8 +61,6 @@ module.exports = function(config, server) { const namespace = getNamespace(config) // debug('namespace', namespace) const nsps = generateWss(namespace, config) - // debug('nsps', nsps) - // debug('nsps', nsps); // we will always call it via a namespace server.on('upgrade', function upgrade(req, socket, head) { const pathname = getPath(req) @@ -72,11 +70,11 @@ module.exports = function(config, server) { srv.handleUpgrade(req, socket, head, function done(ws) { debug('found a srv to handle the call') srv.emit('connection', ws, req) - }); + }) } else { debug('Unhandled socket destroy') socket.destroy() } - }); - return nsps; + }) + return nsps } diff --git a/packages/ws-server/lib/ws/ws-setup.js b/packages/ws-server/src/core/ws-setup.js similarity index 91% rename from packages/ws-server/lib/ws/ws-setup.js rename to packages/ws-server/src/core/ws-setup.js index 11f5dac1b50c46800e584aa1a38eab359b167fd2..7a2546fd097d484dcdfb6caa4122f4d394c1f1f2 100644 --- a/packages/ws-server/lib/ws/ws-setup.js +++ b/packages/ws-server/src/core/ws-setup.js @@ -1,6 +1,6 @@ // ws setup const { finalCatch } = require('jsonql-errors') -const { wsGetUserdata, groupByNamespace } = require('jsonql-jwt') +const { packError, groupByNamespace } = require('jsonql-utils') const { isNotEmpty, validateAsync } = require('jsonql-params-validator') const { LOGOUT_EVT_NAME, @@ -8,9 +8,13 @@ const { ERROR_TYPE, LOGOUT_NAME } = require('jsonql-constants') + +const { + getDebug, + createWsReply, + getUserdata +} = require('../share/helpers') const resolveMethod = require('../share/resolve-method') -const { getDebug, packError } = require('../share/helpers') -const createWsReply = require('./create-ws-reply') const debug = getDebug('ws-setup') @@ -29,7 +33,7 @@ const fnHandler = (ws, payload, resolverName, params, opts, userdata) => { const cb = data => { ws.send(data) } - // run + // @NOTE the params.params is from the contract return validateAsync(payload.args, params.params, true) .then( args => { return resolveMethod( @@ -49,7 +53,7 @@ const fnHandler = (ws, payload, resolverName, params, opts, userdata) => { } }) .catch(err => { - debug('catch error', err) + debug('CATCH RESOLVER ERROR', err) cb(createWsReply(ERROR_TYPE, resolverName, packError(err))) }) } @@ -91,7 +95,7 @@ const wsSetup = (opts, nspObj) => { let nspInfo = {}; const socketFns = opts.contract.socket; if (opts.enableAuth) { - nspInfo = groupByNamespace(socketFns) + nspInfo = groupByNamespace(socketFns, true) } let { publicNamespace, nspSet } = nspInfo; for (let namespace in nspObj) { @@ -115,7 +119,7 @@ const wsSetup = (opts, nspObj) => { if (methodsInNsp[resolverName]) { // only the private one will get a userdata property if (namespace !== publicNamespace) { - userdata = wsGetUserdata(req) + userdata = getUserdata(req) } callNspHandler(ws, json, socketFns, opts, userdata) } diff --git a/packages/ws-server/src/index.js b/packages/ws-server/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..baf1739a99d0676ddc3e276f3a495dbaeef0d7e5 --- /dev/null +++ b/packages/ws-server/src/index.js @@ -0,0 +1,10 @@ +// re-export here +const { wsSetup, wsCreateServer } = require('./core') +const checkOptions = require('./check-options') + +// re-export +module.exports = { + checkOptions, + wsSetup, + wsCreateServer +} diff --git a/packages/ws-server/lib/share/constants.js b/packages/ws-server/src/share/constants.js similarity index 100% rename from packages/ws-server/lib/share/constants.js rename to packages/ws-server/src/share/constants.js diff --git a/packages/ws-server/lib/share/get-contract.js b/packages/ws-server/src/share/get-contract.js similarity index 77% rename from packages/ws-server/lib/share/get-contract.js rename to packages/ws-server/src/share/get-contract.js index 02c0b6b40e979947144e350741a602c36079cac2..c43462f4c71c62d36160723ee7b8029f54115e8b 100644 --- a/packages/ws-server/lib/share/get-contract.js +++ b/packages/ws-server/src/share/get-contract.js @@ -2,20 +2,22 @@ const { join } = require('path') const fsx = require('fs-extra') const { DEFAULT_CONTRACT_FILE_NAME } = require('jsonql-constants') -const { isContract } = require('jsonql-params-validator') +const { isContract } = require('jsonql-utils') const { JsonqlError } = require('jsonql-errors') const { CONTRACT_NOT_FOUND_ERR } = require('./constants') + /** + * get the contract with validation * @param {object} config configuration * @return {object} config with the contract */ -module.exports = function(config) { +module.exports = function getContract(config) { if (config.contract && isContract(config.contract)) { return config; } let c = fsx.readJsonSync(join(config.contractDir, DEFAULT_CONTRACT_FILE_NAME)) if (!isContract(c)) { - throw new JsonqlError(CONTRACT_NOT_FOUND_ERR ) + throw new JsonqlError(CONTRACT_NOT_FOUND_ERR) } config.contract = c; return config; diff --git a/packages/ws-server/lib/share/helpers.js b/packages/ws-server/src/share/helpers.js similarity index 63% rename from packages/ws-server/lib/share/helpers.js rename to packages/ws-server/src/share/helpers.js index 05d84083b8c3c69d33317e88fd21639fcbc78bbd..6c2be255340c20faa09d65f86da96b3ffc37327e 100644 --- a/packages/ws-server/lib/share/helpers.js +++ b/packages/ws-server/src/share/helpers.js @@ -1,12 +1,12 @@ // util methods -const { trim } = require('lodash') const debug = require('debug') // jsonql libraries const { JSONQL_PATH, WS_REPLY_TYPE, WS_EVT_NAME, - WS_DATA_NAME + WS_DATA_NAME, + ERROR_KEY } = require('jsonql-constants') const { isString, @@ -16,17 +16,36 @@ const { JsonqlError, clientErrorsHandler } = require('jsonql-errors') +const { toJson, packError } = require('jsonql-utils') const { MODULE_NAME } = require('./constants') - // create debug const getDebug = name => debug(MODULE_NAME).extend(name) - const _debug = getDebug('helpers') +const WS_KEYS = [ WS_REPLY_TYPE, WS_EVT_NAME, WS_DATA_NAME ] + +const { merge } = require('lodash') + + + +/** + * The ws doesn't have a acknowledge callback like socket.io + * so we have to DIY one for ws and other that doesn't have it + * @param {string} type of reply + * @param {string} resolverName which is replying + * @param {*} data payload + * @return {string} stringify json + */ +const createWsReply = (type, resolverName, data) => { + return JSON.stringify({ + data: { + [WS_REPLY_TYPE]: type, + [WS_EVT_NAME]: resolverName, + [WS_DATA_NAME]: toJson(data) + } + }) +} -// import { getDebug } from '../get-debug'; -const keys = [ WS_REPLY_TYPE, WS_EVT_NAME, WS_DATA_NAME ] -// const debug = getDebug('is-ws-reply'); /** * @param {string|object} payload should be string when reply but could be transformed * @return {boolean} true is OK @@ -35,8 +54,8 @@ const isWsReply = payload => { const json = isString(payload) ? JSON.parse(payload) : payload; const { data } = json; if (data) { - let result = keys.filter(key => isKeyInObject(data, key)) - return (result.length === keys.length) ? data : false; + let result = WS_KEYS.filter(key => isKeyInObject(data, key)) + return (result.length === WS_KEYS.length) ? data : false; } return false; } @@ -46,14 +65,16 @@ const isWsReply = payload => { * @return {object} false on failed */ const extractWsPayload = payload => { - const json = isString(payload) ? JSON.parse(payload) : payload; + const json = toJson(payload) + // if there is error then this will throw - clientErrorsHandler(json); + // this was never handled? + clientErrorsHandler(json) // now handle the data let _data; if ((_data = isWsReply(json)) !== false) { return { - data: _data[WS_DATA_NAME], + data: toJson(_data[WS_DATA_NAME]), resolverName: _data[WS_EVT_NAME], type: _data[WS_REPLY_TYPE] } @@ -81,45 +102,25 @@ const getNamespace = function(config) { return [ base ] } -/** - * From underscore.string library - * @BUG there is a bug here with the non-standard name - * @param {string} str string - * @return {string} dasherize string - */ -const dasherize = str => trim(str) - .replace(/([A-Z])/g, '-$1') - .replace(/[-_\s]+/g, '-') - .toLowerCase() - -/** - * create the error message - * @param {object} e error - * @param {boolean} s true toString - * @return {object} formatted reply - */ -const packError = (e, s = false) => { - const payload = { - error: { - className: e.className || 'JsonqlServerError', - message: e.message || 'NO MESSAGE', - detail: e.detail || e - } - } - return s ? JSON.stringify(payload) : payload; -} - // just an empty method for addProperty getter const nil = function() { return false; } +/** + * @param {object} req the request object + * @return {object} userdata + */ +function getUserdata(req) { + return req && req.state && req.state.userdata ? req.state.userdata : false; +} + // export module.exports = { + createWsReply, getDebug, getNamespace, - dasherize, - packError, extractWsPayload, - nil + nil, + getUserdata } diff --git a/packages/ws-server/src/share/resolve-method.js b/packages/ws-server/src/share/resolve-method.js new file mode 100644 index 0000000000000000000000000000000000000000..e4686315a5efc3c2087506f1d5198ec5af26a552 --- /dev/null +++ b/packages/ws-server/src/share/resolve-method.js @@ -0,0 +1,62 @@ +// search for the resolver location +const fs = require('fs') +const { join } = require('path') +const { isUndefined } = require('lodash') +const { + JsonqlAuthorisationError, + JsonqlResolverNotFoundError, + JsonqlResolverAppError, + JsonqlValidationError, + JsonqlError, + finalCatch +} = require('jsonql-errors') +const { + SOCKET_NAME, + DEFAULT_RESOLVER_IMPORT_FILE_NAME, + MODULE_TYPE +} = require('jsonql-constants') +const { validateSync } = require('jsonql-params-validator') +const { provideUserdata } = require('jsonql-jwt') +const { dasherize, injectToFn } = require('jsonql-utils') + +const debug = require('debug')('jsonql-ws-server:resolve-method') + +const { getResolver } = require('jsonql-resolver') + +/** + * using the serverType to provide different addProperty method to this + * @param {function} fn the resolver function + * @param {string} resolverName resolver name + * @param {object} ws the different context object + * @param {object|boolean} userdata false when there is none + * @return {function} the applied function + */ +const addProperty = (fn, resolverName, ws, userdata) => { + let _fn = injectToFn(fn, resolverName, ws) + // group the provide userdata together + return isUndefined(userdata) ? _fn : provideUserdata(_fn, userdata) +} + +/** + * similiar to the one in Koa-middleware without the ctx + * @param {string} resolverName name to call + * @param {array} args arguments + * @param {object} params extracted params + * @param {object} opts for search later + * @param {object} ws the WebSocket instance + * @param {object} [userdata=false] userdata + * @return {mixed} depends on the contract + */ +const resolveMethod = function(resolverName, args, params, opts, ws, userdata = false) { + // the contract is always part of the options here + const fn = getResolver(resolverName, SOCKET_NAME, opts.contract, opts) + const tfn = addProperty(fn, resolverName, ws, userdata) + try { + return Reflect.apply(tfn, null, args) + } catch(e) { + throw new JsonqlResolverAppError(resolverName, e) + } +} + +// we only need to export one method +module.exports = resolveMethod diff --git a/packages/ws-server/tests/fixtures/es6resolvers/import.js b/packages/ws-server/tests/fixtures/es6resolvers/import.js deleted file mode 100644 index 6601f782c3497ae953db86928e4e6e922da04a10..0000000000000000000000000000000000000000 --- a/packages/ws-server/tests/fixtures/es6resolvers/import.js +++ /dev/null @@ -1,2 +0,0 @@ -require = require("esm")(module/*, options*/) -module.exports = require("./resolver.js") diff --git a/packages/ws-server/tests/fixtures/es6resolvers/resolver.js b/packages/ws-server/tests/fixtures/es6resolvers/resolver.js deleted file mode 100644 index e61e6a77a607f32bc219b1d8560eb49a919214ec..0000000000000000000000000000000000000000 --- a/packages/ws-server/tests/fixtures/es6resolvers/resolver.js +++ /dev/null @@ -1,19 +0,0 @@ -import querygetSomething from './query/get-something.js' -import mutationsaveSomething from './mutation/save-something.js' -import authlogin from './auth/login.js' -import authlogout from './auth/logout.js' -import socketcauseError from './socket/cause-error.js' -import socketchatroom from './socket/chatroom.js' -import socketdelayFn from './socket/delay-fn.js' -import socketwsHandler from './socket/ws-handler.js' - -export { - querygetSomething, -mutationsaveSomething, -authlogin, -authlogout, -socketcauseError, -socketchatroom, -socketdelayFn, -socketwsHandler -} \ No newline at end of file diff --git a/packages/ws-server/tests/ws-connect-error.test.js b/packages/ws-server/tests/ws-connect-error.test.js new file mode 100644 index 0000000000000000000000000000000000000000..0bbb2ef063ef15065d6490693dc8a787026e5af3 --- /dev/null +++ b/packages/ws-server/tests/ws-connect-error.test.js @@ -0,0 +1,75 @@ +// testing the Error handling +const test = require('ava') + +const { join } = require('path') +const fsx = require('fs-extra') + +const wsNodeClient = require('../client') + +const wsServer = require('./fixtures/server') +const { JSONQL_PATH, ERROR_TYPE } = require('jsonql-constants') +const debug = require('debug')('jsonql-ws-server:test:ws') + +const contractDir = join(__dirname, 'fixtures', 'contract') +const contractFile = join(contractDir, 'contract.json'); +const contract = fsx.readJsonSync(contractFile); + +const { extractWsPayload } = require('../src/share/helpers') +const createPayload = require('./fixtures/create-payload') +const port = 8899; +const msg = 'Something'; +let ctn = 0; + +test.before(async t => { + const { app, io } = await wsServer({ + contractDir, + contract + }) + t.context.io = io; + t.context.server = app; + t.context.server.listen(port) + + t.context.client = wsNodeClient(`ws://localhost:${port}/${JSONQL_PATH}`) +}) + +test.after(t => { + t.context.server.close() +}) + +test.cb(`It should able to extract the error object when error throw from the server side`, t => { + t.plan(4) + // connect to the server + let client = t.context.client; + + client.on('open', () => { + client.send( createPayload('causeError', msg + ' 3nd') ) + }) + + // wait for reply + client.on('message', msg => { + let json; + try { + debug('on message received: %O', msg) + + json = extractWsPayload(msg) + let { data } = json; + debug('json decoded from msg: %O', data) + // data.error = typeof data.error === 'string' ? JSON.parse(data.error) : data.error; + + t.truthy(data.error, 'causeError should have error field') + t.is(data.error.className, 'JsonqlResolverAppError') + t.is(json.type, ERROR_TYPE) + + // The same problem happens again + // data.error.className === 'JsonqlResolverAppError' + // it returned a JsonqlError again + t.is(json.resolverName, 'causeError') + + t.end() + + } catch(e) { + debug('error happens in the catch phrase and end the test', e) + t.end() + } + }) +}) diff --git a/packages/ws-server/tests/ws-connect-es6.test.js b/packages/ws-server/tests/ws-connect-es6.test.js index 395e9ca0451905999c8a63139ed47ec8fe985b34..8ba3064f8a4351a3331123311a0e98dd2a924610 100644 --- a/packages/ws-server/tests/ws-connect-es6.test.js +++ b/packages/ws-server/tests/ws-connect-es6.test.js @@ -1,10 +1,10 @@ // test the basic connection and such const test = require('ava') -// const WebSocket = require('ws') + const { join } = require('path') const fsx = require('fs-extra') -const { wsNodeClient } = require('jsonql-jwt') +const wsNodeClient = require('../client') const wsServer = require('./fixtures/server') const { JSONQL_PATH, ERROR_TYPE } = require('jsonql-constants') @@ -15,9 +15,9 @@ const resolverDir = join(__dirname, 'fixtures', 'es6resolvers') const contractFile = join(contractDir, 'contract.json') const contract = fsx.readJsonSync(contractFile) -const { extractWsPayload } = require('../lib/share/helpers') +const { extractWsPayload } = require('../src/share/helpers') const createPayload = require('./fixtures/create-payload') -const port = 8898; +const port = 8897; const msg = 'Something'; let ctn = 0; @@ -36,14 +36,13 @@ test.before(async t => { test.after(t => { t.context.server.close() -}); +}) test.cb('Grouping all test together as one because the way ws reponse to on.message', t => { - t.plan(6); + t.plan(8) // connect to the server let client = t.context.client; - t.is(true , t.context.io[JSONQL_PATH] !== undefined) client.on('open', () => { @@ -54,21 +53,34 @@ test.cb('Grouping all test together as one because the way ws reponse to on.mess setTimeout(() => { client.send( createPayload('causeError', msg + ' 3nd') ) }, 500) - }) + let i = 0; + + const shouldEnd = (ctn, t) => { + if (ctn > 2) { + t.end() + } + } + // wait for reply client.on('message', (data) => { + // (1) + t.is(true , t.context.io[JSONQL_PATH] !== undefined) let json; try { json = extractWsPayload(data) debug('on message received: ', json) switch (json.resolverName) { case 'wsHandler': + // (2) t.truthy(json.data, 'wsHandler should reply with a message') + shouldEnd(++i, t) break; case 'chatroom': + // (3) t.truthy(json.data, 'chatroom should reply with a message') + shouldEnd(++i, t) break; default: debug('catch error here %O', json) @@ -78,7 +90,7 @@ test.cb('Grouping all test together as one because the way ws reponse to on.mess t.is(json.type, ERROR_TYPE) t.true(data.error.className === 'JsonqlResolverAppError' && data.error.message === 'causeError') - t.end() + shouldEnd(++i, t) } } catch(e) { @@ -92,5 +104,5 @@ test.cb('Grouping all test together as one because the way ws reponse to on.mess t.end() } - }); -}); + }) +}) diff --git a/packages/ws-server/tests/ws-connect.test.js b/packages/ws-server/tests/ws-connect.test.js index f44d437ec1204b914a992de8afd8f58b6a7a0fe9..f7a121208f78ab341ea931a4573086234052e5ed 100644 --- a/packages/ws-server/tests/ws-connect.test.js +++ b/packages/ws-server/tests/ws-connect.test.js @@ -4,7 +4,7 @@ const test = require('ava') const { join } = require('path') const fsx = require('fs-extra') -const { wsNodeClient } = require('jsonql-jwt') +const wsNodeClient = require('../client') const wsServer = require('./fixtures/server') const { JSONQL_PATH, ERROR_TYPE } = require('jsonql-constants') @@ -14,7 +14,7 @@ const contractDir = join(__dirname, 'fixtures', 'contract') const contractFile = join(contractDir, 'contract.json'); const contract = fsx.readJsonSync(contractFile); -const { extractWsPayload } = require('../lib/share/helpers') +const { extractWsPayload } = require('../src/share/helpers') const createPayload = require('./fixtures/create-payload') const port = 8898; const msg = 'Something'; @@ -30,29 +30,21 @@ test.before(async t => { t.context.server.listen(port) t.context.client = wsNodeClient(`ws://localhost:${port}/${JSONQL_PATH}`) -}); +}) test.after(t => { t.context.server.close() -}); +}) test.cb('Grouping all test together as one because the way ws reponse to on.message', t => { - t.plan(6); + t.plan(3) + let tested = 0; // connect to the server let client = t.context.client; - t.is(true , t.context.io[JSONQL_PATH] !== undefined) - client.on('open', () => { - client.send( createPayload('wsHandler', msg + ' 1st', Date.now()) ) - client.send( createPayload('chatroom', msg + ' 2nd', Date.now()) ) - - setTimeout(() => { - client.send( createPayload('causeError', msg + ' 3nd') ) - }, 500) - }) // wait for reply @@ -60,35 +52,29 @@ test.cb('Grouping all test together as one because the way ws reponse to on.mess let json; try { json = extractWsPayload(data) + debug('on message received: ', json) + switch (json.resolverName) { case 'wsHandler': + ++tested; t.truthy(json.data, 'wsHandler should reply with a message') + if (tested > 1) { + t.end() + } break; case 'chatroom': t.truthy(json.data, 'chatroom should reply with a message') + ++tested; + if (tested > 1) { + t.end() + } break; default: - debug('catch error here %O', json) - let { data } = json; - - t.truthy(data.error, 'causeError should have error field') - t.is(json.type, ERROR_TYPE) - t.true(data.error.className === 'JsonqlResolverAppError' && data.error.message === 'causeError') - - t.end() } } catch(e) { - - debug('error', e) - /* - let { data } = error; - t.true(data.error.className === 'JsonqlResolverAppError' && data.error.message === 'causeError') - t.is(data.error.type, ERROR_TYPE) - t.truthy(data.error, 'causeError should have error field') - */ - + debug('error happens in the catch phrase and end the test', e) t.end() } - }); -}); + }) +}) diff --git a/packages/ws-server/tests/ws-jwt-auth.test.js b/packages/ws-server/tests/ws-jwt-auth.test.js index 836d2583301659c048c50483fbd867829c1a0ba8..e48b9ed2d6f0ae72602cb50716e0be770b8c7b4f 100644 --- a/packages/ws-server/tests/ws-jwt-auth.test.js +++ b/packages/ws-server/tests/ws-jwt-auth.test.js @@ -2,19 +2,21 @@ const test = require('ava') const { join } = require('path') const fsx = require('fs-extra') // this will get the umd version of the client module -const { wsNodeAuthClient, wsNodeClient, decodeToken } = require('jsonql-jwt') -// const WebSocket = require('ws') -const { extractWsPayload } = require('../lib/share/helpers') - -const debug = require('debug')('jsonql-ws-server:test:jwt-auth') const { JSONQL_PATH } = require('jsonql-constants') -const contractDir = join(__dirname, 'fixtures', 'contract', 'auth') -const contract = fsx.readJsonSync(join(contractDir, 'contract.json')) +const { decodeToken } = require('jsonql-jwt') + +const wsNodeClient = require('../client') +const { extractWsPayload } = require('../src/share/helpers') const serverSetup = require('./fixtures/server') const createToken = require('./fixtures/token') const createPayload = require('./fixtures/create-payload') -const payload = {name: 'Joel'}; +const debug = require('debug')('jsonql-ws-server:test:jwt-auth') + +const contractDir = join(__dirname, 'fixtures', 'contract', 'auth') +const contract = fsx.readJsonSync(join(contractDir, 'contract.json')) + +const payload = {name: 'Joel'} const port = 3003; test.before(async t => { @@ -34,11 +36,10 @@ test.before(async t => { t.context.app.listen(port) const baseUrl = `ws://localhost:${port}/${JSONQL_PATH}/`; - + // @1.3.0 there is no different between the two only need the token param now t.context.client_public = wsNodeClient(baseUrl + 'public') - t.context.client_private = wsNodeAuthClient(baseUrl + 'private', t.context.token) - + t.context.client_private = wsNodeClient(baseUrl + 'private', t.context.token) }) test.after(t => { @@ -77,7 +78,7 @@ test.cb('It should able to connect to the private namespace', t => { }) client.on('message', data => { - let json = extractWsPayload(data); + let json = extractWsPayload(data) t.truthy(json.data) debug(json) t.end()