diff --git a/packages/@jsonql/socketio/package.json b/packages/@jsonql/socketio/package.json index 033d269f7ae75a25e0c29cee26c7a2756fcb3887..e67109eedfc3b834b654e67601e1716f0b220de8 100644 --- a/packages/@jsonql/socketio/package.json +++ b/packages/@jsonql/socketio/package.json @@ -4,7 +4,18 @@ "description": "Socket.io client / server module for jsonql", "main": "index.js", "scripts": { - "test": "ava" + "test": "ava --verbose", + "test:browser:io": "DEBUG=jsonql-ws-client*,server-io-core* NODE_ENV=io node ./tests/browser/run-qunit.js", + "test:browser:hs": "DEBUG=jsonql-ws-client* node NODE_ENV=hs ./tests/browser/run-qunit.js", + "test:browser:rt": "DEBUG=jsonql-ws-client* node NODE_ENV=rt ./tests/browser/run-qunit.js", + "test:node": "npm run build:test && DEBUG=jsonql-* ava ./tests/test-node.test.js", + "test:chain": "DEBUG=jsonql-ws-client* ava ./tests/io-chain-connection.test.js", + + "test:io": "npm run build:cjs && DEBUG=jsonql-ws-* ava ./tests/io-client.test.js", + "test:io:hs": "npm run build:cjs && DEBUG=jsonql-*,-jsonql-ws-client:nb-event-service ava ./tests/io-client-hs-auth.test.js", + "test:io:hs:login": "npm run build:cjs && DEBUG=jsonql-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-hs-auth-login.test.js", + "test:io:rt": "npm run build:cjs && DEBUG=jsonql-ws-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-rt-auth.test.js", + "test:io:rt:login": "npm run build:cjs && DEBUG=jsonql-ws-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-rt-auth-login.test.js" }, "keywords": [ "jsonql", @@ -14,5 +25,59 @@ "node" ], "author": "Joel Chu ", - "license": "ISC" + "license": "ISC", + "homepage": "jsonql.js.org", + "devDependencies": { + "ava": "^2.2.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.4", + "jsonql-contract": "^1.7.7", + "jsonql-koa": "^1.3.7", + "jsonql-ws-server": "^1.2.0", + "koa": "^2.7.0", + "koa-bodyparser": "^4.2.1", + "rollup": "^1.19.4", + "rollup-plugin-alias": "^1.5.2", + "rollup-plugin-async": "^1.2.0", + "rollup-plugin-buble": "^0.19.8", + "rollup-plugin-bundle-size": "^1.0.3", + "rollup-plugin-commonjs": "^10.0.2", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-node-builtins": "^2.1.2", + "rollup-plugin-node-globals": "^1.4.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-replace": "^2.2.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^5.1.1", + "rollup-pluginutils": "^2.8.1", + "server-io-core": "^1.2.0", + "sorcery": "^0.10.0", + "ws": "^7.1.2", + "kefir": "^3.8.6" + }, + "ava": { + "files": [ + "tests/*.test.js", + "!tests/helpers/*.*", + "!tests/fixtures/*.*", + "!tests/jwt/*.*" + ], + "require": [ + "esm" + ], + "cache": true, + "concurrency": 5, + "failFast": true, + "failWithoutAssertions": false, + "tap": false, + "compileEnhancements": false + }, + "engine": { + "node": ">=8" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@gitee.com:to1source/jsonql.git" + } } diff --git a/packages/ws-client/rollup.config.js b/packages/@jsonql/socketio/rollup.config.js similarity index 100% rename from packages/ws-client/rollup.config.js rename to packages/@jsonql/socketio/rollup.config.js diff --git a/packages/ws-client/rollup.config.node.js b/packages/@jsonql/socketio/rollup.config.node.js similarity index 100% rename from packages/ws-client/rollup.config.node.js rename to packages/@jsonql/socketio/rollup.config.node.js diff --git a/packages/jwt/rollup.socket-io-client.config.js b/packages/@jsonql/socketio/rollup.socket-io-client.config.js similarity index 97% rename from packages/jwt/rollup.socket-io-client.config.js rename to packages/@jsonql/socketio/rollup.socket-io-client.config.js index 0c4c5e05e3c0160b467341d5968fd8138c6b59c5..b21b6dfbcf26ee5c37261597ac96b338fc49d374 100644 --- a/packages/jwt/rollup.socket-io-client.config.js +++ b/packages/@jsonql/socketio/rollup.socket-io-client.config.js @@ -28,7 +28,7 @@ let plugins = [ buble({ objectAssign: 'Object.assign' }), - nodeResolve(), + nodeResolve({ preferBuiltins: true }), commonjs({ include: 'node_modules/**' }), diff --git a/packages/jwt/src/client/socketio/chain-connect-async.js b/packages/@jsonql/socketio/src/client/chain-connect-async.js similarity index 98% rename from packages/jwt/src/client/socketio/chain-connect-async.js rename to packages/@jsonql/socketio/src/client/chain-connect-async.js index 8bd088d6deb65ed778622aa175abc399eb18e933..fc17ca80eb17886bed1ed48bcd17d41d7389f6a5 100644 --- a/packages/jwt/src/client/socketio/chain-connect-async.js +++ b/packages/@jsonql/socketio/src/client/chain-connect-async.js @@ -1,15 +1,16 @@ // this will combine two namespaces and chain them together in a promises chain // to ensure the auth connection established first -import { chainPromises } from '../utils' +import { chainPromises } from 'jsonql-utils' +import { IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN } from 'jsonql-constants' +import { JsonqlValidationError } from 'jsonql-errors' +import { isObject } from 'jsonql-params-validator' + import { socketIoHandshakeLogin, socketIoClientAsync } from './handshake-login' import socketIoRoundtripLogin from './roundtrip-login' -import { IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN } from 'jsonql-constants' -import { JsonqlValidationError } from 'jsonql-errors' -import { isObject } from 'jsonql-params-validator' /** * Type of client * @param {string} type for checking diff --git a/packages/jwt/src/client/socketio/chain-connect.js b/packages/@jsonql/socketio/src/client/chain-connect.js similarity index 98% rename from packages/jwt/src/client/socketio/chain-connect.js rename to packages/@jsonql/socketio/src/client/chain-connect.js index c636d6c699579c18d6548325ef02cd597fa8a2ab..6576e6bd46f2d55f6e4bed86de0f6831d8997a7b 100644 --- a/packages/jwt/src/client/socketio/chain-connect.js +++ b/packages/@jsonql/socketio/src/client/chain-connect.js @@ -1,15 +1,16 @@ // this will combine two namespaces and chain them together in a promises chain // to ensure the auth connection established first -import { chainPromises } from '../utils' +import { chainPromises } from 'jsonql-utils' +import { IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN } from 'jsonql-constants' +import { JsonqlValidationError } from 'jsonql-errors' +import { isObject } from 'jsonql-params-validator' + import { socketIoHandshakeLogin, socketIoClientAsync } from './handshake-login' import socketIoRoundtripLogin from './roundtrip-login' -import { IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN } from 'jsonql-constants' -import { JsonqlValidationError } from 'jsonql-errors' -import { isObject } from 'jsonql-params-validator' /** * Type of client * @param {string} type for checking diff --git a/packages/jwt/src/client/socketio/handshake-login.js b/packages/@jsonql/socketio/src/client/handshake-login.js similarity index 100% rename from packages/jwt/src/client/socketio/handshake-login.js rename to packages/@jsonql/socketio/src/client/handshake-login.js diff --git a/packages/jwt/src/client/socketio/index.js b/packages/@jsonql/socketio/src/client/index.js similarity index 100% rename from packages/jwt/src/client/socketio/index.js rename to packages/@jsonql/socketio/src/client/index.js diff --git a/packages/jwt/src/client/socketio/roundtrip-login.js b/packages/@jsonql/socketio/src/client/roundtrip-login.js similarity index 100% rename from packages/jwt/src/client/socketio/roundtrip-login.js rename to packages/@jsonql/socketio/src/client/roundtrip-login.js diff --git a/packages/jwt/src/client/socketio/socket-io-client.js b/packages/@jsonql/socketio/src/client/socket-io-client.js similarity index 100% rename from packages/jwt/src/client/socketio/socket-io-client.js rename to packages/@jsonql/socketio/src/client/socket-io-client.js diff --git a/packages/ws-client/src/io/create-client.js b/packages/@jsonql/socketio/src/io/create-client.js similarity index 99% rename from packages/ws-client/src/io/create-client.js rename to packages/@jsonql/socketio/src/io/create-client.js index a8986f5dfb64247abdfb57773add769c63bac563..8c4c8ae25ab277ff17204a64e8490bc56d541e22 100644 --- a/packages/ws-client/src/io/create-client.js +++ b/packages/@jsonql/socketio/src/io/create-client.js @@ -78,8 +78,6 @@ const createNsps = function(opts, nspMap, token) { })) } - - /** * This is just copy of the ws version we need to figure * out how to deal with the roundtrip login later diff --git a/packages/ws-client/src/io/index.js b/packages/@jsonql/socketio/src/io/index.js similarity index 100% rename from packages/ws-client/src/io/index.js rename to packages/@jsonql/socketio/src/io/index.js diff --git a/packages/ws-client/src/io/io-main-handler.js b/packages/@jsonql/socketio/src/io/io-main-handler.js similarity index 100% rename from packages/ws-client/src/io/io-main-handler.js rename to packages/@jsonql/socketio/src/io/io-main-handler.js diff --git a/packages/@jsonql/socketio/src/server/clients.js b/packages/@jsonql/socketio/src/server/clients.js new file mode 100644 index 0000000000000000000000000000000000000000..d6a99a42e7d0dced8e8ab515909df8c93a071559 --- /dev/null +++ b/packages/@jsonql/socketio/src/server/clients.js @@ -0,0 +1,2139 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var jsonqlErrors = require('jsonql-errors'); +require('debug'); +require('jsonql-params-validator'); + +// this should work on browser as well as node +// import io from 'socket.io-cilent' + +/** + * Create a normal client + * @param {object} io socket io instance + * @param {string} url end point + * @param {object} [options={}] configuration + * @return {object} nsp instance + */ +function socketIoClient(io, url, options) { + if ( options === void 0 ) options = {}; + + return io.connect(url, options) +} + +// this is the default time to wait for reply if exceed this then we +// trigger an error --> 5 seconds +var DEFAULT_WS_WAIT_TIME = 5000; +var TOKEN_PARAM_NAME = 'token'; +var IO_ROUNDTRIP_LOGIN = 'roundtip'; +var IO_HANDSHAKE_LOGIN = 'handshake'; + +// handshake login + +/** + * Create a async version to match up the rest of the api + * @param {object} io socket io instance + * @param {string} url end point + * @param {object} [options={}] configuration + * @return {object} Promise resolve to nsp instance + */ +function socketIoClientAsync() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return Promise.resolve( + Reflect.apply(socketIoClient, null, args) + ) +} + +/** + * Login during handshake + * @param {object} io the new socket.io instance + * @param {string} token to send + * @param {object} [options = {}] extra options + * @return {object} the io object itself + */ +function socketIoHandshakeLogin(io, url, token, options) { + if ( options === void 0 ) options = {}; + + var wait = options.timeout || DEFAULT_WS_WAIT_TIME; + var config = Object.assign({}, options, { + query: [TOKEN_PARAM_NAME, token].join('=') + }); + var timer; + var nsp = socketIoClient(io, url, config); + return new Promise(function (resolver, rejecter) { + timer = setTimeout(function () { + rejecter(); + }, wait); + nsp.on('connect', function () { + console.info('socketIoHandshakeLogin connected'); + resolver(nsp); + clearTimeout(timer); + }); + }) +} + +// import { isString } from 'jsonql-params-validator'; +/** + * The core method of the socketJwt client side + * @param {object} socket the socket.io connected instance + * @param {string} token for validation + * @param {function} onAuthenitcated callback when authenticated + * @param {function} onUnauthorized callback when authorized + * @return {void} + */ +var socketIoLoginAction = function (socket, token, onAuthenticated, onUnauthorized) { + socket + .emit('authenticate', { token: token }) + .on('authenticated', onAuthenticated) + .on('unauthorized', onUnauthorized); +}; + +/** + * completely rethink about how the browser version should be! + * + */ +function socketIoRoundtripLogin(io, url, token, options) { + + var socket = socketIoClient(io, url); + return new Promise(function (resolver, rejecter) { + socketIoLoginAction(socket, token, function () { return resolver(socket); } , rejecter); + }) +} + +var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + +var lookup = []; +var revLookup = []; +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; +var inited = false; +function init () { + inited = true; + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + + revLookup['-'.charCodeAt(0)] = 62; + revLookup['_'.charCodeAt(0)] = 63; +} + +function toByteArray (b64) { + if (!inited) { + init(); + } + var i, j, l, tmp, placeHolders, arr; + var len = b64.length; + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len; + + var L = 0; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; + arr[L++] = (tmp >> 16) & 0xFF; + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); + arr[L++] = tmp & 0xFF; + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp; + var output = []; + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output.push(tripletToBase64(tmp)); + } + return output.join('') +} + +function fromByteArray (uint8) { + if (!inited) { + init(); + } + var tmp; + var len = uint8.length; + var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes + var output = ''; + var parts = []; + var maxChunkLength = 16383; // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1]; + output += lookup[tmp >> 2]; + output += lookup[(tmp << 4) & 0x3F]; + output += '=='; + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); + output += lookup[tmp >> 10]; + output += lookup[(tmp >> 4) & 0x3F]; + output += lookup[(tmp << 2) & 0x3F]; + output += '='; + } + + parts.push(output); + + return parts.join('') +} + +function read (buffer, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? (nBytes - 1) : 0; + var d = isLE ? -1 : 1; + var s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +function write (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); + var i = isLE ? 0 : (nBytes - 1); + var d = isLE ? 1 : -1; + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; +} + +var toString = {}.toString; + +var isArray = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +var INSPECT_MAX_BYTES = 50; + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length); + } + that.length = length; + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192; // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype; + return arr +}; + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +}; + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype; + Buffer.__proto__ = Uint8Array; +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size); + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +}; + +function allocUnsafe (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0; + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +}; +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +}; + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0; + that = createBuffer(that, length); + + var actual = that.write(string, encoding); + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual); + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0; + that = createBuffer(that, length); + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255; + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength; // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array); + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset); + } else { + array = new Uint8Array(array, byteOffset, length); + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array); + } + return that +} + +function fromObject (that, obj) { + if (internalIsBuffer(obj)) { + var len = checked(obj.length) | 0; + that = createBuffer(that, len); + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len); + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} +Buffer.isBuffer = isBuffer; +function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!internalIsBuffer(a) || !internalIsBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) { return 0 } + + var x = a.length; + var y = b.length; + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break + } + } + + if (x < y) { return -1 } + if (y < x) { return 1 } + return 0 +}; + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +}; + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer.allocUnsafe(length); + var pos = 0; + for (i = 0; i < list.length; ++i) { + var buf = list[i]; + if (!internalIsBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer +}; + +function byteLength (string, encoding) { + if (internalIsBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string; + } + + var len = string.length; + if (len === 0) { return 0 } + + // Use a for loop to avoid recursion + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) { return utf8ToBytes(string).length } // assume utf8 + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +} +Buffer.byteLength = byteLength; + +function slowToString (encoding, start, end) { + var loweredCase = false; + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0; + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length; + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0; + start >>>= 0; + + if (end <= start) { + return '' + } + + if (!encoding) { encoding = 'utf8'; } + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } + encoding = (encoding + '').toLowerCase(); + loweredCase = true; + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true; + +function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length; + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1); + } + return this +}; + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length; + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this +}; + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length; + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this +}; + +Buffer.prototype.toString = function toString () { + var length = this.length | 0; + if (length === 0) { return '' } + if (arguments.length === 0) { return utf8Slice(this, 0, length) } + return slowToString.apply(this, arguments) +}; + +Buffer.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } + if (this === b) { return true } + return Buffer.compare(this, b) === 0 +}; + +Buffer.prototype.inspect = function inspect () { + var str = ''; + var max = INSPECT_MAX_BYTES; + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' '); + if (this.length > max) { str += ' ... '; } + } + return '' +}; + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!internalIsBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0; + } + if (end === undefined) { + end = target ? target.length : 0; + } + if (thisStart === undefined) { + thisStart = 0; + } + if (thisEnd === undefined) { + thisEnd = this.length; + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0; + end >>>= 0; + thisStart >>>= 0; + thisEnd >>>= 0; + + if (this === target) { return 0 } + + var x = thisEnd - thisStart; + var y = end - start; + var len = Math.min(x, y); + + var thisCopy = this.slice(thisStart, thisEnd); + var targetCopy = target.slice(start, end); + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i]; + y = targetCopy[i]; + break + } + } + + if (x < y) { return -1 } + if (y < x) { return 1 } + return 0 +}; + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) { return -1 } + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = 0; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + byteOffset = +byteOffset; // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1); + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) { byteOffset = buffer.length + byteOffset; } + if (byteOffset >= buffer.length) { + if (dir) { return -1 } + else { byteOffset = buffer.length - 1; } + } else if (byteOffset < 0) { + if (dir) { byteOffset = 0; } + else { return -1 } + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding); + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (internalIsBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF; // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1; + var arrLength = arr.length; + var valLength = val.length; + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase(); + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2; + arrLength /= 2; + valLength /= 2; + byteOffset /= 2; + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i; + if (dir) { + var foundIndex = -1; + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) { foundIndex = i; } + if (i - foundIndex + 1 === valLength) { return foundIndex * indexSize } + } else { + if (foundIndex !== -1) { i -= i - foundIndex; } + foundIndex = -1; + } + } + } else { + if (byteOffset + valLength > arrLength) { byteOffset = arrLength - valLength; } + for (i = byteOffset; i >= 0; i--) { + var found = true; + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false; + break + } + } + if (found) { return i } + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +}; + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +}; + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +}; + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0; + var remaining = buf.length - offset; + if (!length) { + length = remaining; + } else { + length = Number(length); + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2 !== 0) { throw new TypeError('Invalid hex string') } + + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(parsed)) { return i } + buf[offset + i] = parsed; + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8'; + length = this.length; + offset = 0; + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0; + if (isFinite(length)) { + length = length | 0; + if (encoding === undefined) { encoding = 'utf8'; } + } else { + encoding = length; + length = undefined; + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset; + if (length === undefined || length > remaining) { length = remaining; } + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) { encoding = 'utf8'; } + + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +}; + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +}; + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return fromByteArray(buf) + } else { + return fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end); + var res = []; + + var i = start; + while (i < end) { + var firstByte = buf[i]; + var codePoint = null; + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1; + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint; + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte; + } + break + case 2: + secondByte = buf[i + 1]; + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint; + } + } + break + case 3: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint; + } + } + break + case 4: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + fourthByte = buf[i + 3]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint; + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD; + bytesPerSequence = 1; + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000; + res.push(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + res.push(codePoint); + i += bytesPerSequence; + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000; + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length; + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = ''; + var i = 0; + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ); + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F); + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]); + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length; + + if (!start || start < 0) { start = 0; } + if (!end || end < 0 || end > len) { end = len; } + + var out = ''; + for (var i = start; i < end; ++i) { + out += toHex(buf[i]); + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end); + var res = ''; + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length; + start = ~~start; + end = end === undefined ? len : ~~end; + + if (start < 0) { + start += len; + if (start < 0) { start = 0; } + } else if (start > len) { + start = len; + } + + if (end < 0) { + end += len; + if (end < 0) { end = 0; } + } else if (end > len) { + end = len; + } + + if (end < start) { end = start; } + + var newBuf; + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer(sliceLen, undefined); + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start]; + } + } + + return newBuf +}; + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) { throw new RangeError('offset is not uint') } + if (offset + ext > length) { throw new RangeError('Trying to access beyond buffer length') } +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + + return val +}; + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + checkOffset(offset, byteLength, this.length); + } + + var val = this[offset + --byteLength]; + var mul = 1; + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul; + } + + return val +}; + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + return this[offset] +}; + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return this[offset] | (this[offset + 1] << 8) +}; + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return (this[offset] << 8) | this[offset + 1] +}; + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +}; + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +}; + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + mul *= 0x80; + + if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } + + return val +}; + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var i = byteLength; + var mul = 1; + var val = this[offset + --i]; + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul; + } + mul *= 0x80; + + if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } + + return val +}; + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + if (!(this[offset] & 0x80)) { return (this[offset]) } + return ((0xff - this[offset] + 1) * -1) +}; + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + var val = this[offset] | (this[offset + 1] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + var val = this[offset + 1] | (this[offset] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +}; + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +}; + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, true, 23, 4) +}; + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, false, 23, 4) +}; + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, true, 52, 8) +}; + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, false, 52, 8) +}; + +function checkInt (buf, value, offset, ext, max, min) { + if (!internalIsBuffer(buf)) { throw new TypeError('"buffer" argument must be a Buffer instance') } + if (value > max || value < min) { throw new RangeError('"value" argument is out of bounds') } + if (offset + ext > buf.length) { throw new RangeError('Index out of range') } +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var mul = 1; + var i = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var i = byteLength - 1; + var mul = 1; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } + if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + this[offset] = (value & 0xff); + return offset + 1 +}; + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) { value = 0xffff + value + 1; } + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8; + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) { value = 0xffffffff + value + 1; } + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff; + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24); + this[offset + 2] = (value >>> 16); + this[offset + 1] = (value >>> 8); + this[offset] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = 0; + var mul = 1; + var sub = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = byteLength - 1; + var mul = 1; + var sub = 0; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } + if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + if (value < 0) { value = 0xff + value + 1; } + this[offset] = (value & 0xff); + return offset + 1 +}; + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + this[offset + 2] = (value >>> 16); + this[offset + 3] = (value >>> 24); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (value < 0) { value = 0xffffffff + value + 1; } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) { throw new RangeError('Index out of range') } + if (offset < 0) { throw new RangeError('Index out of range') } +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4); + } + write(buf, value, offset, littleEndian, 23, 4); + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +}; + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8); + } + write(buf, value, offset, littleEndian, 52, 8); + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +}; + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) { start = 0; } + if (!end && end !== 0) { end = this.length; } + if (targetStart >= target.length) { targetStart = target.length; } + if (!targetStart) { targetStart = 0; } + if (end > 0 && end < start) { end = start; } + + // Copy 0 bytes; we're done + if (end === start) { return 0 } + if (target.length === 0 || this.length === 0) { return 0 } + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) { throw new RangeError('sourceStart out of bounds') } + if (end < 0) { throw new RangeError('sourceEnd out of bounds') } + + // Are we oob? + if (end > this.length) { end = this.length; } + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start; + } + + var len = end - start; + var i; + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start]; + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start]; + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ); + } + + return len +}; + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start; + start = 0; + end = this.length; + } else if (typeof end === 'string') { + encoding = end; + end = this.length; + } + if (val.length === 1) { + var code = val.charCodeAt(0); + if (code < 256) { + val = code; + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255; + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0; + end = end === undefined ? this.length : end >>> 0; + + if (!val) { val = 0; } + + var i; + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val; + } + } else { + var bytes = internalIsBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()); + var len = bytes.length; + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len]; + } + } + + return this +}; + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g; + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, ''); + // Node converts strings with length < 2 to '' + if (str.length < 2) { return '' } + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '='; + } + return str +} + +function stringtrim (str) { + if (str.trim) { return str.trim() } + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) { return '0' + n.toString(16) } + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity; + var codePoint; + var length = string.length; + var leadSurrogate = null; + var bytes = []; + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + continue + } + + // valid lead + leadSurrogate = codePoint; + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + leadSurrogate = codePoint; + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + } + + leadSurrogate = null; + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) { break } + bytes.push(codePoint); + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) { break } + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) { break } + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) { break } + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF); + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo; + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) { break } + + c = str.charCodeAt(i); + hi = c >> 8; + lo = c % 256; + byteArray.push(lo); + byteArray.push(hi); + } + + return byteArray +} + + +function base64ToBytes (str) { + return toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) { break } + dst[i + offset] = src[i]; + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + + +// the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +function isBuffer(obj) { + return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) +} + +function isFastBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) +} + +if (typeof global$1.setTimeout === 'function') ; +if (typeof global$1.clearTimeout === 'function') ; + +// from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js +var performance = global$1.performance || {}; +var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + +// this will combine two namespaces and chain them together in a promises chain + +/** + * Type of client + * @param {string} type for checking + * @return {function} or throw error + */ +function getAuthClient(type) { + console.info('client type: ', type); + switch (type) { + case IO_ROUNDTRIP_LOGIN: + return socketIoRoundtripLogin; + case IO_HANDSHAKE_LOGIN: + return socketIoHandshakeLogin; + default: + throw new jsonqlErrors.JsonqlValidationError('socketIoChainConnect', {message: ("Unknown " + type + " of client!")}) + } +} + +/** + * @param {object} io socket.io-client + * @param {string} baseUrl to connect + * @param {array} namespaces to append to baseUrl + * @param {string} token for validation + * @param {array} options passing to the clients + * @param {string} [ type = IO_HANDSHAKE_LOGIN ] of client to use + * @return {object} promise resolved n*nsps in order + */ +function socketIoChainConnect(io, baseUrl, namespaces, token, type, options) { + if ( type === void 0 ) type = IO_HANDSHAKE_LOGIN; + + // we expect the order is auth url first + return new Promise(function (resolver, rejecter) { + var authUrl = [baseUrl, namespaces[0]].join(''); + var fn1 = Reflect.apply(getAuthClient(type), null, [io, authUrl, token]); + fn1.then(function (nsp1) { + var publicUrl = [baseUrl, namespaces[1]].join(''); + var fn2 = Reflect.apply(socketIoClientAsync, null, [io, publicUrl]); + fn2.then(function (nsp2) { + resolver([nsp1, nsp2]); + }) + .catch(function (err2) { + rejecter({message: ("failed on " + publicUrl), error: err2}); + }); + }) + .catch(function (err1) { + rejecter({message: ("failed on " + authUrl), error: err1}); + }); + }) +} + +exports.socketIoChainConnect = socketIoChainConnect; +exports.socketIoClient = socketIoClient; +exports.socketIoClientAsync = socketIoClientAsync; +exports.socketIoHandshakeLogin = socketIoHandshakeLogin; +exports.socketIoRoundtripLogin = socketIoRoundtripLogin; diff --git a/packages/jwt/src/server/socketio/get-userdata.js b/packages/@jsonql/socketio/src/server/get-userdata.js similarity index 100% rename from packages/jwt/src/server/socketio/get-userdata.js rename to packages/@jsonql/socketio/src/server/get-userdata.js diff --git a/packages/jwt/src/server/socketio/handshake-auth.js b/packages/@jsonql/socketio/src/server/handshake-auth.js similarity index 100% rename from packages/jwt/src/server/socketio/handshake-auth.js rename to packages/@jsonql/socketio/src/server/handshake-auth.js diff --git a/packages/jwt/src/server/socketio/socketio-jwt-auth.js b/packages/@jsonql/socketio/src/server/socketio-jwt-auth.js similarity index 100% rename from packages/jwt/src/server/socketio/socketio-jwt-auth.js rename to packages/@jsonql/socketio/src/server/socketio-jwt-auth.js diff --git a/packages/ws-client/src/node/socketio-clients.js b/packages/@jsonql/socketio/src/socketio-clients.js similarity index 100% rename from packages/ws-client/src/node/socketio-clients.js rename to packages/@jsonql/socketio/src/socketio-clients.js diff --git a/packages/ws-client/tests/browser/files/simple-test.js b/packages/@jsonql/socketio/tests/browser/files/simple-test.js similarity index 100% rename from packages/ws-client/tests/browser/files/simple-test.js rename to packages/@jsonql/socketio/tests/browser/files/simple-test.js diff --git a/packages/ws-client/tests/browser/run-qunit.js b/packages/@jsonql/socketio/tests/browser/run-qunit.js similarity index 100% rename from packages/ws-client/tests/browser/run-qunit.js rename to packages/@jsonql/socketio/tests/browser/run-qunit.js diff --git a/packages/ws-client/tests/browser/webroot/index.html b/packages/@jsonql/socketio/tests/browser/webroot/index.html similarity index 100% rename from packages/ws-client/tests/browser/webroot/index.html rename to packages/@jsonql/socketio/tests/browser/webroot/index.html diff --git a/packages/ws-client/tests/browser/webroot/qunit-log.js b/packages/@jsonql/socketio/tests/browser/webroot/qunit-log.js similarity index 100% rename from packages/ws-client/tests/browser/webroot/qunit-log.js rename to packages/@jsonql/socketio/tests/browser/webroot/qunit-log.js diff --git a/packages/@jsonql/socketio/tests/fixtures/contract-config-auth.js b/packages/@jsonql/socketio/tests/fixtures/contract-config-auth.js new file mode 100644 index 0000000000000000000000000000000000000000..25fd9e0d39c1b5e34e1c62f590488e1f05c83421 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract-config-auth.js @@ -0,0 +1,10 @@ + +const { join } = require('path'); + +module.exports = { + contractDir: join(__dirname, 'contract', 'auth'), + resolverDir: join(__dirname, 'resolvers'), + public: true, + enableAuth: true, + useJwt: true +} diff --git a/packages/@jsonql/socketio/tests/fixtures/contract-config.js b/packages/@jsonql/socketio/tests/fixtures/contract-config.js new file mode 100644 index 0000000000000000000000000000000000000000..2187de94e54e2a3a8dc0fa0b7d8e115c83644e8d --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract-config.js @@ -0,0 +1,9 @@ + +const { join } = require('path'); + +module.exports = { + contractDir: join(__dirname, 'contract', 'auth'), + resolverDir: join(__dirname, 'resolvers'), + enableAuth: true, + useJwt: true +}; diff --git a/packages/@jsonql/socketio/tests/fixtures/contract/auth/contract.json b/packages/@jsonql/socketio/tests/fixtures/contract/auth/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..72510498a1edea8f1eb2f2f5ea6a9970c66d8ba6 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract/auth/contract.json @@ -0,0 +1,111 @@ +{ + "query": {}, + "mutation": {}, + "auth": {}, + "timestamp": 1560348254, + "socket": { + "continuous": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/continuous.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "pinging": { + "namespace": "jsonql/public", + "public": true, + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/public/pinging.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "reply message based on your message" + } + ] + }, + "sendExtraMsg": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/send-extra-msg.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/simple.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/throw-error.js", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/socketio/tests/fixtures/contract/auth/public-contract.json b/packages/@jsonql/socketio/tests/fixtures/contract/auth/public-contract.json new file mode 100644 index 0000000000000000000000000000000000000000..62d35ef6f9fff4c98ffe37e6d8299614c4f6a797 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract/auth/public-contract.json @@ -0,0 +1,117 @@ +{ + "query": { + "helloWorld": { + "description": "This is the stock resolver for testing purpose", + "params": [], + "returns": [ + { + "type": "string", + "description": "stock message" + } + ] + } + }, + "mutation": {}, + "auth": {}, + "timestamp": 1560348254, + "socket": { + "continuous": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "pinging": { + "namespace": "jsonql/public", + "public": true, + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "reply message based on your message" + } + ] + }, + "sendExtraMsg": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "namespace": "jsonql/private", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/socketio/tests/fixtures/contract/contract.json b/packages/@jsonql/socketio/tests/fixtures/contract/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..3728746dba80315150bf4d5c1b555326f0e25c17 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract/contract.json @@ -0,0 +1,84 @@ +{ + "query": {}, + "mutation": {}, + "auth": {}, + "timestamp": 1560347818, + "socket": { + "continuous": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/continuous.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "sendExtraMsg": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/send-extra-msg.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/simple.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/throw-error.js", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/socketio/tests/fixtures/contract/public-contract.json b/packages/@jsonql/socketio/tests/fixtures/contract/public-contract.json new file mode 100644 index 0000000000000000000000000000000000000000..43cfd2b37fce72eec46df65703bb5e054e015c0f --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/contract/public-contract.json @@ -0,0 +1,91 @@ +{ + "query": { + "helloWorld": { + "description": "This is the stock resolver for testing purpose", + "params": [], + "returns": [ + { + "type": "string", + "description": "stock message" + } + ] + } + }, + "mutation": {}, + "auth": {}, + "timestamp": 1560347818, + "socket": { + "continuous": { + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "sendExtraMsg": { + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/socketio/tests/fixtures/io-setup.js b/packages/@jsonql/socketio/tests/fixtures/io-setup.js new file mode 100644 index 0000000000000000000000000000000000000000..65f37ec3a20f81671372c3ef0d88b6abdc857ec0 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/io-setup.js @@ -0,0 +1,23 @@ +// const Koa = require('koa'); +const bodyparser = require('koa-bodyparser'); +const jsonqlWsServer = require('jsonql-ws-server'); +const config = require('./contract-config'); +const { join } = require('path'); +const fsx = require('fs-extra'); +const contract = fsx.readJsonSync(join(config.contractDir, 'contract.json')); +const debug = require('debug')('jsonql-ws-client:fixtures:io-setup'); +const baseOptions = { + serverType: 'socket.io', + contract +}; + +module.exports = function(app, _config = {}) { + const opts = Object.assign(baseOptions, config, _config); + return new Promise(resolver => { + jsonqlWsServer(opts, app) + .then(io => { + debug('setup completed'); + resolver({ app, io }); + }); + }); +} diff --git a/packages/@jsonql/socketio/tests/fixtures/keys/privateKey.pem b/packages/@jsonql/socketio/tests/fixtures/keys/privateKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..52ceae92066efead75838933d8bca25eeb9666ac --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/keys/privateKey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDfDqpnh8TceIRuemm8GWM6nvE6KumK/Lq+POrZqghgHpZa5zjv +wwjsJ2iK45zWIRpggMkSlQZWvnRRjj/TWfv7448qhhiTB7hmqV63XjfYXJ5OgTtN +fPW36ZQ48Ha0y4sjlU4gvSijHpnzrJ5yV/vjLLLp9WxTux4ColeZu2B/XQIDAQAB +AoGAEmLJFQOR7IJamCiq8oA9N6XGSH8lBPnUAr5OtWZYjmO3DQMmJE01PRH6gghE +8zmDTRUQfeGexiOovtg01p0CMhehwS8D8d0m01s43zQ77xVJuFAvuW1U1kER4Xze +tVkLEvvO9PcWpKUEmxYpDoCJXGIfXuHaSAVbVLYDKn2MEUECQQD4FeWlpkxSNQT9 +u6w01zR/byjXzUmibOP5zrpaEsDGIxxTlxc/7WJZlKLNybXUyZE8oHgepuefdcL0 +ybk6gvQpAkEA5ixdMtnsbUImJYNFrt5BbLzEU9eF76hovsOSjOc2eTUJHEeiXeDA +Q66WZwXNBf/CRrZdsAvBPMQcWzJLwp24FQJBAPaojtPMLEXwAS5l0ioXblLlqq4l +pfigW2qcaBv2WUSm1BsoNi2RUB/Q8K26x9bxMj4dLlELkW+yHkxT5J6QZUECQFRO +A4TQlOwfwmETB77Y4RW2viIHWqNBB7x3XYIGXclfR4r4IdxIqaMgmy34zfNYjgvg +V8hXRdu/6LLuZRlPM1ECQHUppZNG7WKP9F7ywAr33u3xD0+9MqsfqcgKPfP9VOxs +Lo8EdmjmB30lyyP/Cd1hzxb+BsJjGmxzU/DikGbWos8= +-----END RSA PRIVATE KEY----- diff --git a/packages/@jsonql/socketio/tests/fixtures/keys/publicKey.pem b/packages/@jsonql/socketio/tests/fixtures/keys/publicKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..7bd2532afbeb5b3be8b9c9f275ffac7b32456d0d --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/keys/publicKey.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfDqpnh8TceIRuemm8GWM6nvE6 +KumK/Lq+POrZqghgHpZa5zjvwwjsJ2iK45zWIRpggMkSlQZWvnRRjj/TWfv7448q +hhiTB7hmqV63XjfYXJ5OgTtNfPW36ZQ48Ha0y4sjlU4gvSijHpnzrJ5yV/vjLLLp +9WxTux4ColeZu2B/XQIDAQAB +-----END PUBLIC KEY----- diff --git a/packages/@jsonql/socketio/tests/fixtures/node/index.js b/packages/@jsonql/socketio/tests/fixtures/node/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3d6f0446b8b240a89dc38c981c0744c4f40509ac --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/node/index.js @@ -0,0 +1,8 @@ +const clientGenerator = require('../../../src/node/client-generator') +const { chainCreateNsps, es } = require('./test.cjs') + +module.exports = { + clientGenerator, + chainCreateNsps, + es +} diff --git a/packages/@jsonql/socketio/tests/fixtures/node/test.cjs.js b/packages/@jsonql/socketio/tests/fixtures/node/test.cjs.js new file mode 100644 index 0000000000000000000000000000000000000000..0a8cb3e84de1444f5962e1a9d6930cee7a8466a8 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/node/test.cjs.js @@ -0,0 +1,720 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var debug = _interopDefault(require('debug')); + +/** + * Try to normalize it to use between browser and node + * @param {string} name for the debug output + * @return {function} debug + */ +var getDebug = function (name) { + if (debug) { + return debug('jsonql-ws-client').extend(name) + } + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + console.info.apply(null, [name].concat(args)); + } +}; +try { + if (window && window.localStorage) { + localStorage.setItem('DEBUG', 'jsonql-ws-client*'); + } +} catch(e) {} + +var NB_EVENT_SERVICE_PRIVATE_STORE = new WeakMap(); +var NB_EVENT_SERVICE_PRIVATE_LAZY = new WeakMap(); + +/** + * generate a 32bit hash based on the function.toString() + * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery + * @param {string} s the converted to string function + * @return {string} the hashed function string + */ +function hashCode(s) { + return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0) +} + +// this is the new implementation without the hash key +// export +var EventService = function EventService(config) { + if ( config === void 0 ) config = {}; + + if (config.logger && typeof config.logger === 'function') { + this.logger = config.logger; + } + this.keep = config.keep; + // for the $done setter + this.result = config.keep ? [] : null; + // we need to init the store first otherwise it could be a lot of checking later + this.normalStore = new Map(); + this.lazyStore = new Map(); +}; + +var prototypeAccessors = { $done: { configurable: true },normalStore: { configurable: true },lazyStore: { configurable: true } }; + +/** + * logger function for overwrite + */ +EventService.prototype.logger = function logger () {}; + +////////////////////////// +// PUBLIC METHODS // +////////////////////////// + +/** + * Register your evt handler, note we don't check the type here, + * we expect you to be sensible and know what you are doing. + * @param {string} evt name of event + * @param {function} callback bind method --> if it's array or not + * @param {object} [context=null] to execute this call in + * @return {number} the size of the store + */ +EventService.prototype.$on = function $on (evt , callback , context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + var type = 'on'; + this.validate(evt, callback); + // first need to check if this evt is in lazy store + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register first then call later + if (lazyStoreContent === false) { + this.logger('$on', (evt + " callback is not in lazy store")); + // @TODO we need to check if there was other listener to this + // event and are they the same type then we could solve that + // register the different type to the same event name + + return this.addToNormalStore(evt, type, callback, context) + } + this.logger('$on', (evt + " found in lazy store")); + // this is when they call $trigger before register this callback + var size = 0; + lazyStoreContent.forEach(function (content) { + var payload = content[0]; + var ctx = content[1]; + var t = content[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + size += this$1.addToNormalStore(evt, type, callback, context || ctx); + }); + return size; +}; + +/** + * once only registered it once, there is no overwrite option here + * @NOTE change in v1.3.0 $once can add multiple listeners + * but once the event fired, it will remove this event (see $only) + * @param {string} evt name + * @param {function} callback to execute + * @param {object} [context=null] the handler execute in + * @return {boolean} result + */ +EventService.prototype.$once = function $once (evt , callback , context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'once'; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (lazyStoreContent === false) { + this.logger('$once', (evt + " not in the lazy store")); + // v1.3.0 $once now allow to add multiple listeners + return this.addToNormalStore(evt, type, callback, context) + } else { + // now this is the tricky bit + // there is a potential bug here that cause by the developer + // if they call $trigger first, the lazy won't know it's a once call + // so if in the middle they register any call with the same evt name + // then this $once call will be fucked - add this to the documentation + this.logger('$once', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } +}; + +/** + * This one event can only bind one callbackback + * @param {string} evt event name + * @param {function} callback event handler + * @param {object} [context=null] the context the event handler execute in + * @return {boolean} true bind for first time, false already existed + */ +EventService.prototype.$only = function $only (evt, callback, context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'only'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("$only", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('$only', (evt + " found data in lazy store to execute")); + var list = Array.from(lazyStoreContent); + // $only allow to trigger this multiple time on the single handler + list.forEach( function (l) { + var payload = l[0]; + var ctx = l[1]; + var t = l[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + }); + } + return added; +}; + +/** + * $only + $once this is because I found a very subtile bug when we pass a + * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0 + * @param {string} evt event name + * @param {function} callback to call later + * @param {object} [context=null] exeucte context + * @return {void} + */ +EventService.prototype.$onlyOnce = function $onlyOnce (evt, callback, context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'onlyOnce'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("$onlyOnce", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('$onlyOnce', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== 'onlyOnce') { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + return added; +}; + +/** + * This is a shorthand of $off + $on added in V1.5.0 + * @param {string} evt event name + * @param {function} callback to exeucte + * @param {object} [context = null] or pass a string as type + * @param {string} [type=on] what type of method to replace + * @return {} + */ +EventService.prototype.$replace = function $replace (evt, callback, context, type) { + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = 'on'; + + if (this.validateType(type)) { + this.$off(evt); + var method = this['$' + type]; + return Reflect.apply(method, this, [evt, callback, context]) + } + throw new Error((type + " is not supported!")) +}; + +/** + * trigger the event + * @param {string} evt name NOT allow array anymore! + * @param {mixed} [payload = []] pass to fn + * @param {object|string} [context = null] overwrite what stored + * @param {string} [type=false] if pass this then we need to add type to store too + * @return {number} if it has been execute how many times + */ +EventService.prototype.$trigger = function $trigger (evt , payload , context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + this.validateEvt(evt); + var found = 0; + // first check the normal store + var nStore = this.normalStore; + this.logger('$trigger', nStore); + if (nStore.has(evt)) { + this.logger('$trigger', evt, 'found'); + var nSet = Array.from(nStore.get(evt)); + var ctn = nSet.length; + var hasOnce = false; + for (var i=0; i < ctn; ++i) { + ++found; + // this.logger('found', found) + var ref = nSet[i]; + var _ = ref[0]; + var callback = ref[1]; + var ctx = ref[2]; + var type$1 = ref[3]; + this.run(callback, payload, context || ctx); + if (type$1 === 'once' || type$1 === 'onlyOnce') { + hasOnce = true; + } + } + if (hasOnce) { + nStore.delete(evt); + } + return found; + } + // now this is not register yet + this.addToLazyStore(evt, payload, context, type); + return found; +}; + +/** + * this is an alias to the $trigger + * @NOTE breaking change in V1.6.0 we swap the parameter around + * @param {string} evt event name + * @param {*} params pass to the callback + * @param {string} type of call + * @param {object} context what context callback execute in + * @return {*} from $trigger + */ +EventService.prototype.$call = function $call (evt, params, type, context) { + if ( type === void 0 ) type = false; + if ( context === void 0 ) context = null; + + var args = [evt, params]; + args.push(context, type); + return Reflect.apply(this.$trigger, this, args) +}; + +/** + * remove the evt from all the stores + * @param {string} evt name + * @return {boolean} true actually delete something + */ +EventService.prototype.$off = function $off (evt) { + this.validateEvt(evt); + var stores = [ this.lazyStore, this.normalStore ]; + var found = false; + stores.forEach(function (store) { + if (store.has(evt)) { + found = true; + store.delete(evt); + } + }); + return found; +}; + +/** + * return all the listener from the event + * @param {string} evtName event name + * @param {boolean} [full=false] if true then return the entire content + * @return {array|boolean} listerner(s) or false when not found + */ +EventService.prototype.$get = function $get (evt, full) { + if ( full === void 0 ) full = false; + + this.validateEvt(evt); + var store = this.normalStore; + if (store.has(evt)) { + return Array + .from(store.get(evt)) + .map( function (l) { + if (full) { + return l; + } + var key = l[0]; + var callback = l[1]; + return callback; + }) + } + return false; +}; + +/** + * store the return result from the run + * @param {*} value whatever return from callback + */ +prototypeAccessors.$done.set = function (value) { + this.logger('set $done', value); + if (this.keep) { + this.result.push(value); + } else { + this.result = value; + } +}; + +/** + * @TODO is there any real use with the keep prop? + * getter for $done + * @return {*} whatever last store result + */ +prototypeAccessors.$done.get = function () { + if (this.keep) { + this.logger(this.result); + return this.result[this.result.length - 1] + } + return this.result; +}; + +///////////////////////////// +// PRIVATE METHODS // +///////////////////////////// + +/** + * validate the event name + * @param {string} evt event name + * @return {boolean} true when OK + */ +EventService.prototype.validateEvt = function validateEvt (evt) { + if (typeof evt === 'string') { + return true; + } + throw new Error("event name must be string type!") +}; + +/** + * Simple quick check on the two main parameters + * @param {string} evt event name + * @param {function} callback function to call + * @return {boolean} true when OK + */ +EventService.prototype.validate = function validate (evt, callback) { + if (this.validateEvt(evt)) { + if (typeof callback === 'function') { + return true; + } + } + throw new Error("callback required to be function type!") +}; + +/** + * Check if this type is correct or not added in V1.5.0 + * @param {string} type for checking + * @return {boolean} true on OK + */ +EventService.prototype.validateType = function validateType (type) { + var types = ['on', 'only', 'once', 'onlyOnce']; + return !!types.filter(function (t) { return type === t; }).length; +}; + +/** + * Run the callback + * @param {function} callback function to execute + * @param {array} payload for callback + * @param {object} ctx context or null + * @return {void} the result store in $done + */ +EventService.prototype.run = function run (callback, payload, ctx) { + this.logger('run', callback, payload, ctx); + this.$done = Reflect.apply(callback, ctx, this.toArray(payload)); +}; + +/** + * Take the content out and remove it from store id by the name + * @param {string} evt event name + * @param {string} [storeName = lazyStore] name of store + * @return {object|boolean} content or false on not found + */ +EventService.prototype.takeFromStore = function takeFromStore (evt, storeName) { + if ( storeName === void 0 ) storeName = 'lazyStore'; + + var store = this[storeName]; // it could be empty at this point + if (store) { + this.logger('takeFromStore', storeName, store); + if (store.has(evt)) { + var content = store.get(evt); + this.logger('takeFromStore', content); + store.delete(evt); + return content; + } + return false; + } + throw new Error((storeName + " is not supported!")) +}; + +/** + * The add to store step is similar so make it generic for resuse + * @param {object} store which store to use + * @param {string} evt event name + * @param {spread} args because the lazy store and normal store store different things + * @return {array} store and the size of the store + */ +EventService.prototype.addToStore = function addToStore (store, evt) { + var args = [], len = arguments.length - 2; + while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ]; + + var fnSet; + if (store.has(evt)) { + this.logger('addToStore', (evt + " existed")); + fnSet = store.get(evt); + } else { + this.logger('addToStore', ("create new Set for " + evt)); + // this is new + fnSet = new Set(); + } + // lazy only store 2 items - this is not the case in V1.6.0 anymore + // we need to check the first parameter is string or not + if (args.length > 2) { + if (Array.isArray(args[0])) { // lazy store + // check if this type of this event already register in the lazy store + var t = args[2]; + if (!this.checkTypeInLazyStore(evt, t)) { + fnSet.add(args); + } + } else { + if (!this.checkContentExist(args, fnSet)) { + this.logger('addToStore', "insert new", args); + fnSet.add(args); + } + } + } else { // add straight to lazy store + fnSet.add(args); + } + store.set(evt, fnSet); + return [store, fnSet.size] +}; + +/** + * @param {array} args for compare + * @param {object} fnSet A Set to search from + * @return {boolean} true on exist + */ +EventService.prototype.checkContentExist = function checkContentExist (args, fnSet) { + var list = Array.from(fnSet); + return !!list.filter(function (l) { + var hash = l[0]; + if (hash === args[0]) { + return true; + } + return false; + }).length; +}; + +/** + * get the existing type to make sure no mix type add to the same store + * @param {string} evtName event name + * @param {string} type the type to check + * @return {boolean} true you can add, false then you can't add this type + */ +EventService.prototype.checkTypeInStore = function checkTypeInStore (evtName, type) { + this.validateEvt(evtName); + this.validateEvt(type); + var all = this.$get(evtName, true); + if (all === false) { + // pristine it means you can add + return true; + } + // it should only have ONE type in ONE event store + return !all.filter(function (list) { + var t = list[3]; + return type !== t; + }).length; +}; + +/** + * This is checking just the lazy store because the structure is different + * therefore we need to use a new method to check it + */ +EventService.prototype.checkTypeInLazyStore = function checkTypeInLazyStore (evtName, type) { + this.validateEvt(evtName); + this.validateEvt(type); + var store = this.lazyStore.get(evtName); + this.logger('checkTypeInLazyStore', store); + if (store) { + return !!Array + .from(store) + .filter(function (l) { + var t = l[2]; + return t !== type; + }).length + } + return false; +}; + +/** + * wrapper to re-use the addToStore, + * V1.3.0 add extra check to see if this type can add to this evt + * @param {string} evt event name + * @param {string} type on or once + * @param {function} callback function + * @param {object} context the context the function execute in or null + * @return {number} size of the store + */ +EventService.prototype.addToNormalStore = function addToNormalStore (evt, type, callback, context) { + if ( context === void 0 ) context = null; + + this.logger('addToNormalStore', evt, type, 'add to normal store'); + // @TODO we need to check the existing store for the type first! + if (this.checkTypeInStore(evt, type)) { + this.logger((type + " can add to " + evt + " store")); + var key = this.hashFnToKey(callback); + var args = [this.normalStore, evt, key, callback, context, type]; + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.normalStore = _store; + return size; + } + return false; +}; + +/** + * Add to lazy store this get calls when the callback is not register yet + * so we only get a payload object or even nothing + * @param {string} evt event name + * @param {array} payload of arguments or empty if there is none + * @param {object} [context=null] the context the callback execute in + * @param {string} [type=false] register a type so no other type can add to this evt + * @return {number} size of the store + */ +EventService.prototype.addToLazyStore = function addToLazyStore (evt, payload, context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + // this is add in V1.6.0 + // when there is type then we will need to check if this already added in lazy store + // and no other type can add to this lazy store + var args = [this.lazyStore, evt, this.toArray(payload), context]; + if (type) { + args.push(type); + } + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.lazyStore = _store; + return size; +}; + +/** + * make sure we store the argument correctly + * @param {*} arg could be array + * @return {array} make sured + */ +EventService.prototype.toArray = function toArray (arg) { + return Array.isArray(arg) ? arg : [arg]; +}; + +/** + * setter to store the Set in private + * @param {object} obj a Set + */ +prototypeAccessors.normalStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj); +}; + +/** + * @return {object} Set object + */ +prototypeAccessors.normalStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_STORE.get(this) +}; + +/** + * setter to store the Set in lazy store + * @param {object} obj a Set + */ +prototypeAccessors.lazyStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj); +}; + +/** + * @return {object} the lazy store Set + */ +prototypeAccessors.lazyStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this) +}; + +/** + * generate a hashKey to identify the function call + * The build-in store some how could store the same values! + * @param {function} fn the converted to string function + * @return {string} hashKey + */ +EventService.prototype.hashFnToKey = function hashFnToKey (fn) { + return hashCode(fn.toString()) + ''; +}; + +Object.defineProperties( EventService.prototype, prototypeAccessors ); + +// default + +// create a clone version so we know which one we actually is using +var JsonqlWsEvt = /*@__PURE__*/(function (NBEventService) { + function JsonqlWsEvt() { + NBEventService.call(this, {logger: getDebug('nb-event-service')}); + } + + if ( NBEventService ) JsonqlWsEvt.__proto__ = NBEventService; + JsonqlWsEvt.prototype = Object.create( NBEventService && NBEventService.prototype ); + JsonqlWsEvt.prototype.constructor = JsonqlWsEvt; + + var prototypeAccessors = { name: { configurable: true } }; + + prototypeAccessors.name.get = function () { + return 'jsonql-ws-client' + }; + + Object.defineProperties( JsonqlWsEvt.prototype, prototypeAccessors ); + + return JsonqlWsEvt; +}(EventService)); + +// break this out for testing purposes +var debugFn = getDebug('chain-create-nsps'); +/** + * previously we already make sure the order of the namespaces + * and attach the auth client to it + * @param {array} promises array of unresolved promises + * @return {object} promise resolved with the array of promises resolved results + */ +function chainCreateNsps(promises) { + return promises.reduce(function (promiseChain, currentTask) { + debugFn('out %O', currentTask); + return promiseChain.then(function (chainResults) { return ( + currentTask.then(function (currentResult) { return ( + chainResults.concat( [currentResult]) + ); }) + ); }) + }, Promise.resolve([])) +} + +// test inteface to figure out what went wrong with the connection + +/// INIT //// +var es = new JsonqlWsEvt({ + logger: debugFn$1 +}); +var debugFn$1 = debug('jsonql-ws-client:test:cjs'); + +exports.chainCreateNsps = chainCreateNsps; +exports.es = es; diff --git a/packages/@jsonql/socketio/tests/fixtures/node/test.js b/packages/@jsonql/socketio/tests/fixtures/node/test.js new file mode 100644 index 0000000000000000000000000000000000000000..d23876165c43d6be6a66702699fda1989a13e4b5 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/node/test.js @@ -0,0 +1,16 @@ +// test inteface to figure out what went wrong with the connection + +import debug from 'debug' +import ee from '../../../src/utils/ee' +import chainCreateNsps from '../../../src/utils/chain-create-nsps' + +/// INIT //// +const es = new ee({ + logger: debugFn +}) +const debugFn = debug('jsonql-ws-client:test:cjs') + +export { + chainCreateNsps, + es +} diff --git a/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/continuous.js b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/continuous.js new file mode 100644 index 0000000000000000000000000000000000000000..3d468bb97fbe076216fde1fa5137f6c2f0b58dc9 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/continuous.js @@ -0,0 +1,21 @@ +// this will keep sending out message until received a terminate call +let timer; +let ctn = 0; +const debug = require('debug')('jsonql-ws-client:socket:continous') +/** + * @param {string} msg a message + * @return {string} a message with timestamp + */ +module.exports = function continuous(msg) { + if (msg === 'terminate') { + return clearInterval(timer) + } + // use the send setter instead + timer = setInterval(() => { + continuous.send = msg + ` [${++ctn}] ${Date.now()}`; + }, 1000); + // return result + return new Promise((resolver) => { + resolver(`start at ${Date.now()}`) + }); +} diff --git a/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/public/pinging.js b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/public/pinging.js new file mode 100644 index 0000000000000000000000000000000000000000..2cf0735176ab954756f092e9468dfc55f4d42663 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/public/pinging.js @@ -0,0 +1,22 @@ +// this is a public method always avaialble +let ctn = 0; +/** + * @param {string} msg message + * @return {string} reply message based on your message + */ +module.exports = function pinging(msg) { + if (ctn > 0) { + switch (msg) { + case 'ping': + pinging.send = 'pong'; + case 'pong': + pinging.send = 'ping'; + default: + return; + //pinging.send = 'You lose!'; + } + return; + } + ++ctn; + return 'connection established'; +} diff --git a/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/send-extra-msg.js b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/send-extra-msg.js new file mode 100644 index 0000000000000000000000000000000000000000..9144b99adac8272955e4f636174093a38a184604 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/send-extra-msg.js @@ -0,0 +1,12 @@ +// this one will use the property send to send an different message + + +/** + * @param {number} x a number for process + * @return {number} x + ? + */ +module.exports = function sendExtraMsg(x) { + sendExtraMsg.send = x + 2; + + return x + 1; +} diff --git a/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/simple.js b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/simple.js new file mode 100644 index 0000000000000000000000000000000000000000..61810eae68ed7c1c7c2442288d62843acdbd873c --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/simple.js @@ -0,0 +1,9 @@ +// just simple send and process + +/** + * @param {number} i a number + * @return {number} a number + 1; + */ +module.exports = function(i) { + return ++i; +} diff --git a/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/throw-error.js b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/throw-error.js new file mode 100644 index 0000000000000000000000000000000000000000..a7fcd6f4b4bce70b962a312f7abe1c5025852130 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/resolvers/socket/throw-error.js @@ -0,0 +1,9 @@ +// this one will throw an error + +/** + * Testing the throw error + * @return {error} just throw + */ +module.exports = function() { + throw new Error('Shitty Shitty Bang Bang'); +} diff --git a/packages/@jsonql/socketio/tests/fixtures/server-setup.js b/packages/@jsonql/socketio/tests/fixtures/server-setup.js new file mode 100644 index 0000000000000000000000000000000000000000..1bb5ef2be4ac691269b8a6aa5204eda82019a855 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/server-setup.js @@ -0,0 +1,37 @@ +const http = require('http') +const fsx = require('fs-extra') +const { join } = require('path') +const debug = require('debug')('jsonql-ws-client:fixtures:server') +const { JSONQL_PATH } = require('jsonql-constants') + +const resolverDir = join(__dirname, 'resolvers') +const contractDir = join(__dirname, 'contract') +// require('../../../ws-server') +const wsServer = require('jsonql-ws-server') + +// start +const server = http.createServer(function(req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }) + res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2)) + res.end() +}) + +module.exports = function(extra = {}) { + // extra.contract = extra.contract || contract; + return new Promise(resolver => { + wsServer( + Object.assign({ + resolverDir, + contractDir, + serverType: 'ws' + }, extra), + server + ) + .then(io => { + resolver({ + io, + app: server + }); + }) + }); +} diff --git a/packages/@jsonql/socketio/tests/fixtures/token.js b/packages/@jsonql/socketio/tests/fixtures/token.js new file mode 100644 index 0000000000000000000000000000000000000000..b1d444430ce0430ea315ea3e822e7d940f4e0e69 --- /dev/null +++ b/packages/@jsonql/socketio/tests/fixtures/token.js @@ -0,0 +1,16 @@ +// generate token + +const { join } = require('path') +const fsx = require('fs-extra') +const privateKey = fsx.readFileSync(join(__dirname, 'keys', 'privateKey.pem')) +const { jwtRsaToken, jwtToken } = require('jsonql-jwt') +const { HSA_ALGO } = require('jsonql-constants') + +module.exports = function(payload, key = false) { + if (key === false) { + return jwtRsaToken(payload, privateKey) + } + return jwtToken(payload, key, { + algorithm: HSA_ALGO + }) +} diff --git a/packages/ws-client/tests/io-chain-connection.test.js b/packages/@jsonql/socketio/tests/io-chain-connection.test.js similarity index 100% rename from packages/ws-client/tests/io-chain-connection.test.js rename to packages/@jsonql/socketio/tests/io-chain-connection.test.js diff --git a/packages/ws-client/tests/io-client-hs-auth-login.test.js b/packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js similarity index 100% rename from packages/ws-client/tests/io-client-hs-auth-login.test.js rename to packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js diff --git a/packages/ws-client/tests/io-client-hs-auth.test.js b/packages/@jsonql/socketio/tests/io-client-hs-auth.test.js similarity index 100% rename from packages/ws-client/tests/io-client-hs-auth.test.js rename to packages/@jsonql/socketio/tests/io-client-hs-auth.test.js diff --git a/packages/ws-client/tests/io-client-rt-auth-login.test.js b/packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js similarity index 100% rename from packages/ws-client/tests/io-client-rt-auth-login.test.js rename to packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js diff --git a/packages/ws-client/tests/io-client-rt-auth.test.js b/packages/@jsonql/socketio/tests/io-client-rt-auth.test.js similarity index 100% rename from packages/ws-client/tests/io-client-rt-auth.test.js rename to packages/@jsonql/socketio/tests/io-client-rt-auth.test.js diff --git a/packages/ws-client/tests/io-client.test.js b/packages/@jsonql/socketio/tests/io-client.test.js similarity index 100% rename from packages/ws-client/tests/io-client.test.js rename to packages/@jsonql/socketio/tests/io-client.test.js diff --git a/packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js similarity index 100% rename from packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js rename to packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js diff --git a/packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js similarity index 100% rename from packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js rename to packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js diff --git a/packages/ws-client/tests/jwt/socketio-handshake.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js similarity index 100% rename from packages/ws-client/tests/jwt/socketio-handshake.test.js rename to packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js diff --git a/packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js similarity index 100% rename from packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js rename to packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js diff --git a/packages/ws-client/tests/jwt/socketio-roundtrip.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js similarity index 100% rename from packages/ws-client/tests/jwt/socketio-roundtrip.test.js rename to packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js diff --git a/packages/ws-client/tests/jwt/ws-handshake.test.js b/packages/@jsonql/socketio/tests/jwt/ws-handshake.test.js similarity index 100% rename from packages/ws-client/tests/jwt/ws-handshake.test.js rename to packages/@jsonql/socketio/tests/jwt/ws-handshake.test.js diff --git a/packages/@jsonql/socketio/tests/test-node.test.js b/packages/@jsonql/socketio/tests/test-node.test.js new file mode 100644 index 0000000000000000000000000000000000000000..af83dde7f3e942ea4f36d31fa8187fd21326f00d --- /dev/null +++ b/packages/@jsonql/socketio/tests/test-node.test.js @@ -0,0 +1,204 @@ +/// breaking things apart and try to figure out what went wrong at the last step +const test = require('ava') +const debug = require('debug')('jsonql-ws-client:test:node') +/// SERVER SETUP /// +const { join } = require('path') +const fsx = require('fs-extra') + +const serverSetup = require('./fixtures/server-setup') +const genToken = require('./fixtures/token') + +const contractDir = join(__dirname, 'fixtures', 'contract', 'auth') +const contract = fsx.readJsonSync(join(contractDir, 'contract.json')) +const publicContract = fsx.readJsonSync(join(contractDir, 'public-contract.json')) +const { NOT_LOGIN_ERR_MSG, JS_WS_SOCKET_IO_NAME, JS_WS_NAME } = require('jsonql-constants') +const payload = {name: 'Joel'}; +const token = genToken(payload) +const port = 8010; +const url = `ws://localhost:${port}` +//////////////////// +const { + chainCreateNsps, + clientGenerator, + es +} = require('./fixtures/node') + +/// PREPARE TEST /// +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: true, + keysDir: join(__dirname, 'fixtures', 'keys') + }) + + t.context.server = app.listen(port) + + let config = { opts: { serverType: JS_WS_SOCKET_IO_NAME }, nspMap: {}, ee: es }; + let { opts, ee } = clientGenerator(config) + t.context.opts = opts; + t.context.ee = ee; +}) + +// real test start here +test.serial.cb('It should able to replace the same event with new method', t => { + + t.plan(3) + // try a sequence with swapping out the event handler + let ee = t.context.ee; + let evtName = 'main-event'; + let fnName = 'testFn'; + + ee.$on(evtName, (from, value) => { + debug(evtName, from, value) + // (1) + t.is(from, fnName) + return ++value; + }) + // first trigger it + ee.$call(evtName, [fnName, 1]) + // (2) + t.is(ee.$done, 2) + // now replace this event with another callback + ee.$replace(evtName, (from, value) => { + debug(evtName, from, value) + // (3) + t.is(value, 3) + t.end() + return --value; + }) + ee.$call(evtName, [fnName, 3]) +}) + +test.serial.cb.only('It should able to resolve the promise one after the other', t => { + t.plan(1) + let opts = t.context.opts; + let p1 = () => opts.nspAuthClient([url, 'jsonql/private'].join('/'), token) + let p2 = () => opts.nspClient([url, 'jsonql/public'].join('/')) + /* + let p1 = () => new Promise(resolver => { + setTimeout(() => { + resolver('first') + }, 1000) + }) + let p2 = () => new Promise(resolver => { resolver('second') }) + */ + chainCreateNsps([ + p1(), p2() + ]).then(results => { + debug(results) + t.pass() + t.end() + }) +}) + +test.serial.cb('Just test with the ws client can connect to the server normally', t => { + t.plan(2) + let opts = t.context.opts; + + // t.truthy(opts.nspClient) + // t.truthy(opts.nspAuthClient) + + opts.nspAuthClient([url, 'jsonql/private'].join('/'), token) + .then(socket => { + debug('io1 pass') + t.pass() + opts.nspClient([url, 'jsonql/public'].join('/')) + .then( socket => { + debug('io2 pass') + t.pass() + t.end() + }) + }) + + /* + this was for ws + ws1.onopen = function() { + t.pass() + debug('ws1 connected') + } + ws2.onopen = function() { + t.pass() + debug('ws2 connected') + ws1.terminate() + ws2.terminate() + t.end() + } + */ +}) + + +test.serial.cb('It should able to use the chainCreateNsps to run connection in sequence', t => { + t.plan(1) + let opts = t.context.opts; + + // t.truthy(opts.nspClientAsync) + // t.truthy(opts.nspAuthClientAsync) + + opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token) + .then(ws => { + t.pass() + t.end() + }) + + // the bug is the chainCreateNsps somehow when we put it in there + // the connection just hang + + /* + chainCreateNsps([ + opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token), + // opts.nspClientAsync([url, 'jsonql/public'].join('/')) + ]).then(nsps => { + t.is(nsps.length, 2) + nsps.forEach(nsp => { + nsp.terminate() + }) + t.end() + }) + */ +}) + +test.serial.cb.skip('It should able to wrap the connect call with the onopen callback', t => { + t.plan(3) + let opts = t.context.opts; + let ee = t.context.ee; + let publicConnect = () => { + return opts.nspClientAsync([url, 'jsonql/public'].join('/')) + .then(ws => { + ws.onopen = function() { + ee.$trigger('onReady1', ws) + } + return 'jsonql/public' + }) + } + + let privateConnect = () => { + return opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token) + .then(ws => { + ws.onopen = function() { + ee.$trigger('onReady2', ws) + } + return 'jsonql/private' + }) + } + + chainCreateNsps([ + privateConnect(), + publicConnect() + ]).then(namespaces => { + t.is(namespaces.length, 2) + }) + + ee.$on('onReady1', function() { + t.pass() + t.end() + }) + + ee.$on('onReady2', function() { + t.pass() + }) + +}) diff --git a/packages/@jsonql/ws/package.json b/packages/@jsonql/ws/package.json index b431434a23816d0f10b4be53c06bd9925b629c59..1e56c46c0b5ca92d4de1231322b18c59b615a00c 100644 --- a/packages/@jsonql/ws/package.json +++ b/packages/@jsonql/ws/package.json @@ -6,7 +6,13 @@ "module": "index.js", "browser": "dist/jsonql-ws.umd.js", "scripts": { - "test": "ava" + "test": "ava --verbose", + "test:browser": "DEBUG=jsonql-ws-client*,server-io-core* node ./tests/browser/run-qunit.js", + "test:browser:ws:auth": "DEBUG=jsonql-ws-client* NODE_ENV=ws-auth node ./tests/browser/run-qunit.js", + "test:ws": "npm run build:cjs && DEBUG=jsonql-ws-client* ava ./tests/ws-client.test.js", + "test:ws:auth": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava ./tests/ws-client-auth.test.js", + "test:ws:login": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava ./tests/ws-client-auth-login.test.js", + "test:ws:chain": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava --verbose ./tests/ws-client-chain.test.js" }, "keywords": [ "jsonql", @@ -18,5 +24,59 @@ "node" ], "author": "Joel Chu ", - "license": "ISC" + "license": "ISC", + "homepage": "jsonql.js.org", + "devDependencies": { + "ava": "^2.2.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.4", + "jsonql-contract": "^1.7.7", + "jsonql-koa": "^1.3.7", + "jsonql-ws-server": "^1.2.0", + "koa": "^2.7.0", + "koa-bodyparser": "^4.2.1", + "rollup": "^1.19.4", + "rollup-plugin-alias": "^1.5.2", + "rollup-plugin-async": "^1.2.0", + "rollup-plugin-buble": "^0.19.8", + "rollup-plugin-bundle-size": "^1.0.3", + "rollup-plugin-commonjs": "^10.0.2", + "rollup-plugin-copy": "^3.1.0", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-node-builtins": "^2.1.2", + "rollup-plugin-node-globals": "^1.4.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-replace": "^2.2.0", + "rollup-plugin-serve": "^1.0.1", + "rollup-plugin-terser": "^5.1.1", + "rollup-pluginutils": "^2.8.1", + "server-io-core": "^1.2.0", + "sorcery": "^0.10.0", + "ws": "^7.1.2", + "kefir": "^3.8.6" + }, + "ava": { + "files": [ + "tests/*.test.js", + "!tests/helpers/*.*", + "!tests/fixtures/*.*", + "!tests/jwt/*.*" + ], + "require": [ + "esm" + ], + "cache": true, + "concurrency": 5, + "failFast": true, + "failWithoutAssertions": false, + "tap": false, + "compileEnhancements": false + }, + "engine": { + "node": ">=8" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@gitee.com:to1source/jsonql.git" + } } diff --git a/packages/jwt/rollup.client-utils.config.js b/packages/@jsonql/ws/rollup.config.js similarity index 58% rename from packages/jwt/rollup.client-utils.config.js rename to packages/@jsonql/ws/rollup.config.js index af0ffb6912c360fa8c338d858427daf5332c3e7b..e6d3778e4548c0563e43214e308d055e0a5f7aa2 100644 --- a/packages/jwt/rollup.client-utils.config.js +++ b/packages/@jsonql/ws/rollup.config.js @@ -1,10 +1,11 @@ /** - * Rollup config for just building out the decode token to share between cjs and browser + * Rollup config for browser version of the */ import { join } from 'path' import buble from 'rollup-plugin-buble' -// import { terser } from "rollup-plugin-terser" +import { terser } from "rollup-plugin-terser" + import replace from 'rollup-plugin-replace' import commonjs from 'rollup-plugin-commonjs' @@ -19,16 +20,19 @@ import async from 'rollup-plugin-async' // get the version info import { version } from './package.json' -const env = process.env.NODE_ENV; +const env = process.env.NODE_ENV let plugins = [ json({ preferConst: true }), buble({ - objectAssign: 'Object.assign' + objectAssign: 'Object.assign', + transforms: { dangerousForOf: true } + }), + nodeResolve({ + preferBuiltins: false }), - nodeResolve(), commonjs({ include: 'node_modules/**' }), @@ -37,34 +41,30 @@ let plugins = [ async(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), - '__PLACEHOLDER__': `version: ${version} module: ${env==='prod' ? 'cjs' : 'umd'}` - }), - size() + '__PLACEHOLDER__': `version: ${version} module: umd` + }) ] +if (process.env.NODE_ENV === 'production') { + plugins.push( terser() ) +} +plugins.push( size() ) + let config = { - input: join(__dirname, 'src', 'client', 'utils', 'index.js'), + input: join(__dirname, 'index.js'), output: { - name: 'jsonqlJwtHelpers', - file: join(__dirname, 'src', 'helpers', 'client-utils.js'), - format: 'cjs', - sourceMap: false, + name: 'jsonqlWsClient', + file: join(__dirname, 'dist', 'jsonql-ws-client.js'), + format: 'umd', + sourcemap: true, globals: { - 'jwt-decode': 'jwt_decode', - 'jsonql-params-validator': 'jsonqlParamsValidator', - 'jsonql-errors': 'jsonqlErrors', - 'jsonwebtoken': 'jwt', + 'WebSocket': 'ws', 'socket.io-client': 'io', 'promise-polyfill': 'Promise', 'debug': 'debug' } }, external: [ - 'jwt-decode', - 'jsonql-params-validator', - 'jsonql-errors', - 'jsonwebtoken', - 'jwt', 'WebSocket', 'socket.io-client', 'io', @@ -73,6 +73,6 @@ let config = { 'promise-polyfill' ], plugins: plugins -} +}; export default config; diff --git a/packages/@jsonql/ws/rollup.config.node.js b/packages/@jsonql/ws/rollup.config.node.js new file mode 100644 index 0000000000000000000000000000000000000000..d6c593b758db019b29c1b5dbe9de7f6dd7e3c23e --- /dev/null +++ b/packages/@jsonql/ws/rollup.config.node.js @@ -0,0 +1,85 @@ +/** + * Rollup config this will build the main in cjs version + * then we have another interface to import that and pass the createWsClient call to it + */ +import { join } from 'path' +import buble from 'rollup-plugin-buble' + +// import { terser } from "rollup-plugin-terser"; +import replace from 'rollup-plugin-replace' +import commonjs from 'rollup-plugin-commonjs' + +import json from 'rollup-plugin-json' + +import nodeResolve from 'rollup-plugin-node-resolve' +import nodeGlobals from 'rollup-plugin-node-globals' +import builtins from 'rollup-plugin-node-builtins' +import size from 'rollup-plugin-bundle-size' +// support async functions +import async from 'rollup-plugin-async' +// get the version info +import { version } from './package.json' + +const env = process.env.NODE_ENV; + +let plugins = [ + json({ + preferConst: true + }), + buble({ + objectAssign: 'Object.assign', + transforms: { dangerousForOf: true } + }), + nodeResolve({ + preferBuiltins: false + }), + commonjs({ + include: 'node_modules/**' + }), + nodeGlobals(), + builtins(), + async(), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + '__PLACEHOLDER__': `version: ${version} module: cjs` + }), + size() +] + +const basedir = join(__dirname, 'src') +const mainFile = join(basedir, 'main.js') +const testFile = join(__dirname, 'tests', 'fixtures', 'node', 'test.js') +const mainOutFile = join(basedir, 'node', 'main.cjs.js') +const testOutFile = join(__dirname, 'tests', 'fixtures', 'node', 'test.cjs.js') + +const inputFile = env === 'test' ? testFile : mainFile; +const outputFile = env === 'test' ? testOutFile : mainOutFile; + +console.info(`Input: ${inputFile}\r\noutput: ${outputFile}`) + +let config = { + input: inputFile, + output: { + name: 'jsonqlWsNodeClient', + file: outputFile, + format: 'cjs', + sourcemap: false, + globals: { + 'WebSocket': "ws", + 'socket.io-client': 'io', + 'promise-polyfill': 'Promise', + 'debug': 'debug' + } + }, + external: [ + 'WebSocket', + 'socket.io-client', + 'io', + 'debug', + 'Promise', + 'promise-polyfill' + ], + plugins: plugins +} + +export default config; diff --git a/packages/jwt/src/client/ws/auth-client.js b/packages/@jsonql/ws/src/client/auth-client.js similarity index 100% rename from packages/jwt/src/client/ws/auth-client.js rename to packages/@jsonql/ws/src/client/auth-client.js diff --git a/packages/jwt/src/client/ws/ws.js b/packages/@jsonql/ws/src/client/ws.js similarity index 100% rename from packages/jwt/src/client/ws/ws.js rename to packages/@jsonql/ws/src/client/ws.js diff --git a/packages/jwt/src/server/ws/get-userdata.js b/packages/@jsonql/ws/src/server/get-userdata.js similarity index 100% rename from packages/jwt/src/server/ws/get-userdata.js rename to packages/@jsonql/ws/src/server/get-userdata.js diff --git a/packages/jwt/src/server/ws/verify-client.js b/packages/@jsonql/ws/src/server/verify-client.js similarity index 100% rename from packages/jwt/src/server/ws/verify-client.js rename to packages/@jsonql/ws/src/server/verify-client.js diff --git a/packages/ws-client/src/node/ws-client.js b/packages/@jsonql/ws/src/ws-client.js similarity index 100% rename from packages/ws-client/src/node/ws-client.js rename to packages/@jsonql/ws/src/ws-client.js diff --git a/packages/ws-client/src/ws/create-client.js b/packages/@jsonql/ws/src/ws/create-client.js similarity index 100% rename from packages/ws-client/src/ws/create-client.js rename to packages/@jsonql/ws/src/ws/create-client.js diff --git a/packages/ws-client/src/ws/extract-ws-payload.js b/packages/@jsonql/ws/src/ws/extract-ws-payload.js similarity index 100% rename from packages/ws-client/src/ws/extract-ws-payload.js rename to packages/@jsonql/ws/src/ws/extract-ws-payload.js diff --git a/packages/ws-client/src/ws/index.js b/packages/@jsonql/ws/src/ws/index.js similarity index 100% rename from packages/ws-client/src/ws/index.js rename to packages/@jsonql/ws/src/ws/index.js diff --git a/packages/ws-client/src/ws/ws-main-handler.js b/packages/@jsonql/ws/src/ws/ws-main-handler.js similarity index 100% rename from packages/ws-client/src/ws/ws-main-handler.js rename to packages/@jsonql/ws/src/ws/ws-main-handler.js diff --git a/packages/ws-client/src/ws/ws.js b/packages/@jsonql/ws/src/ws/ws.js similarity index 100% rename from packages/ws-client/src/ws/ws.js rename to packages/@jsonql/ws/src/ws/ws.js diff --git a/packages/@jsonql/ws/tests/browser/files/simple-test.js b/packages/@jsonql/ws/tests/browser/files/simple-test.js new file mode 100644 index 0000000000000000000000000000000000000000..24f733c387a6ff83783c2fb67d9c38b6a73f6c20 --- /dev/null +++ b/packages/@jsonql/ws/tests/browser/files/simple-test.js @@ -0,0 +1,25 @@ + +QUnit.test('It should able to use the client to contact the server with static contract', function(assert) { + var done1 = assert.async() + + var jclient = jsonqlWsClient({ + hostname: 'http://localhost:8001', + serverType: 'socket.io', + contract: contract + }).catch(function(error) { + console.error('init error', error) + }) + + jclient.then(function(client) { + + console.log('client', client) + + client.simple(1) + + client.simple.onResult = function(result) { + console.log('result', 2) + assert.equal(2, result, "Hello world test done") + done1() + } + }) +}) diff --git a/packages/@jsonql/ws/tests/browser/run-qunit.js b/packages/@jsonql/ws/tests/browser/run-qunit.js new file mode 100644 index 0000000000000000000000000000000000000000..5fe81471f349b012c48085df49b24be0f8608879 --- /dev/null +++ b/packages/@jsonql/ws/tests/browser/run-qunit.js @@ -0,0 +1,98 @@ +// this will grab the list of test files +// inject into the html and run the server +const glob = require('glob') +const { join, resolve } = require('path') +const wsServer = require('jsonql-ws-server') +const serverIoCore = require('server-io-core') + +const baseDir = join(__dirname, 'files') +const appBaseDir = resolve(join(__dirname, '..', 'fixtures')) +const contractDir = join(appBaseDir, 'contract') +const resolverDir = join(appBaseDir, 'resolvers') +const contractAuthDir = join(contractDir, 'auth') +const keysDir = join(appBaseDir, 'keys') + +const port = 8001; + +const getConfig = (env) => { + let opts = { + contractDir, + resolverDir, + keysDir, + hostname: `ws://localhost:${port}`, + } + + let envOpts = {} + switch (env) { + case 'io': + envOpts.serverType = 'socket.io'; + break; + case 'hs': + envOpts.serverType = 'socket.io'; + envOpts.enableAuth = true; + envOpts.useJwt = true; + break; + case 'rt': + envOpts.serverType = 'socket.io'; + envOpts.enableAuth = true; + envOpts.useJwt = '12345678'; + break; + case 'ws-auth': + envOpts.enableAuth = true; + envOpts.useJwt = true; + envOpts.serverType = 'ws'; + break; + case 'ws': + default: + envOpts.serverType = 'ws' + break; + } + return Object.assign(opts, envOpts) +} + +const wsServerSetup = (server) => { + const wss = wsServer(getConfig(process.env.NODE_ENV), server) + return wss; // not in use +} + +const runQunit = (open = true) => { + return new Promise((resolver, rejecter) => { + glob(join(baseDir, '*-test.js'), function(err, files) { + if (err) { + console.log('FAILED!', err) + return rejecter(err) + // return process.exit(); + } + // now start the server + const { webserver, app, start } = serverIoCore({ + autoStart: false, + port: port, + webroot: [ + join(__dirname), + join(__dirname, 'webroot'), + join(__dirname, '..', '..', 'node_modules'), + join(__dirname, '..', '..', 'dist') + ], + // open: open, + // this will interface with jsonql-ws-server + socket:false, + reload: false, + debugger: false, + inject: { + insertBefore: false, + target: { + body: files.map( file => file.replace(__dirname, '') ) + } + } + }) + wsServerSetup(webserver) + // now we have a webserver then we could setup the jsonql-ws-server + resolver({ webserver, app, start }) + }) + }) +} + +runQunit() + .then(({ start }) => { + start() + }) diff --git a/packages/@jsonql/ws/tests/browser/webroot/index.html b/packages/@jsonql/ws/tests/browser/webroot/index.html new file mode 100644 index 0000000000000000000000000000000000000000..4f4f45ecfb89dc744b7ba036db1cc75fec5d9ec8 --- /dev/null +++ b/packages/@jsonql/ws/tests/browser/webroot/index.html @@ -0,0 +1,107 @@ + + + + + + QUnit testing for jsonql-client + + + + +
+
+ + + + + + + + + + diff --git a/packages/@jsonql/ws/tests/browser/webroot/qunit-log.js b/packages/@jsonql/ws/tests/browser/webroot/qunit-log.js new file mode 100644 index 0000000000000000000000000000000000000000..9af483abd034c1d31fbd3e0c2999f094f3ef64dc --- /dev/null +++ b/packages/@jsonql/ws/tests/browser/webroot/qunit-log.js @@ -0,0 +1,29 @@ +;(function() { + // testing the QUnit.log method here + // also testing the debug here + var errors = [], i = 0; + + QUnit.log(function(res){ + i++; + if (!res || !res.result){ + // Failure: + errors.push(res) + } + if (i%50 == 0){ + var data = { + tests_run: i, + tracebacks: errors, + url : window.location.pathname + } + errors = []; + } + }) + + QUnit.done(function(results){ + results.tracebacks = errors; + results.url = window.location.pathname; + + console.info('QUnit done', results) + }) + +})(); diff --git a/packages/@jsonql/ws/tests/fixtures/contract-config-auth.js b/packages/@jsonql/ws/tests/fixtures/contract-config-auth.js new file mode 100644 index 0000000000000000000000000000000000000000..25fd9e0d39c1b5e34e1c62f590488e1f05c83421 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract-config-auth.js @@ -0,0 +1,10 @@ + +const { join } = require('path'); + +module.exports = { + contractDir: join(__dirname, 'contract', 'auth'), + resolverDir: join(__dirname, 'resolvers'), + public: true, + enableAuth: true, + useJwt: true +} diff --git a/packages/@jsonql/ws/tests/fixtures/contract-config.js b/packages/@jsonql/ws/tests/fixtures/contract-config.js new file mode 100644 index 0000000000000000000000000000000000000000..2187de94e54e2a3a8dc0fa0b7d8e115c83644e8d --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract-config.js @@ -0,0 +1,9 @@ + +const { join } = require('path'); + +module.exports = { + contractDir: join(__dirname, 'contract', 'auth'), + resolverDir: join(__dirname, 'resolvers'), + enableAuth: true, + useJwt: true +}; diff --git a/packages/@jsonql/ws/tests/fixtures/contract/auth/contract.json b/packages/@jsonql/ws/tests/fixtures/contract/auth/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..72510498a1edea8f1eb2f2f5ea6a9970c66d8ba6 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract/auth/contract.json @@ -0,0 +1,111 @@ +{ + "query": {}, + "mutation": {}, + "auth": {}, + "timestamp": 1560348254, + "socket": { + "continuous": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/continuous.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "pinging": { + "namespace": "jsonql/public", + "public": true, + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/public/pinging.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "reply message based on your message" + } + ] + }, + "sendExtraMsg": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/send-extra-msg.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/simple.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/throw-error.js", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/ws/tests/fixtures/contract/auth/public-contract.json b/packages/@jsonql/ws/tests/fixtures/contract/auth/public-contract.json new file mode 100644 index 0000000000000000000000000000000000000000..62d35ef6f9fff4c98ffe37e6d8299614c4f6a797 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract/auth/public-contract.json @@ -0,0 +1,117 @@ +{ + "query": { + "helloWorld": { + "description": "This is the stock resolver for testing purpose", + "params": [], + "returns": [ + { + "type": "string", + "description": "stock message" + } + ] + } + }, + "mutation": {}, + "auth": {}, + "timestamp": 1560348254, + "socket": { + "continuous": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "pinging": { + "namespace": "jsonql/public", + "public": true, + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "reply message based on your message" + } + ] + }, + "sendExtraMsg": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "namespace": "jsonql/private", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "namespace": "jsonql/private", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/ws/tests/fixtures/contract/contract.json b/packages/@jsonql/ws/tests/fixtures/contract/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..3728746dba80315150bf4d5c1b555326f0e25c17 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract/contract.json @@ -0,0 +1,84 @@ +{ + "query": {}, + "mutation": {}, + "auth": {}, + "timestamp": 1560347818, + "socket": { + "continuous": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/continuous.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "sendExtraMsg": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/send-extra-msg.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/simple.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/throw-error.js", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/ws/tests/fixtures/contract/public-contract.json b/packages/@jsonql/ws/tests/fixtures/contract/public-contract.json new file mode 100644 index 0000000000000000000000000000000000000000..43cfd2b37fce72eec46df65703bb5e054e015c0f --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/contract/public-contract.json @@ -0,0 +1,91 @@ +{ + "query": { + "helloWorld": { + "description": "This is the stock resolver for testing purpose", + "params": [], + "returns": [ + { + "type": "string", + "description": "stock message" + } + ] + } + }, + "mutation": {}, + "auth": {}, + "timestamp": 1560347818, + "socket": { + "continuous": { + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "sendExtraMsg": { + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/@jsonql/ws/tests/fixtures/io-setup.js b/packages/@jsonql/ws/tests/fixtures/io-setup.js new file mode 100644 index 0000000000000000000000000000000000000000..65f37ec3a20f81671372c3ef0d88b6abdc857ec0 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/io-setup.js @@ -0,0 +1,23 @@ +// const Koa = require('koa'); +const bodyparser = require('koa-bodyparser'); +const jsonqlWsServer = require('jsonql-ws-server'); +const config = require('./contract-config'); +const { join } = require('path'); +const fsx = require('fs-extra'); +const contract = fsx.readJsonSync(join(config.contractDir, 'contract.json')); +const debug = require('debug')('jsonql-ws-client:fixtures:io-setup'); +const baseOptions = { + serverType: 'socket.io', + contract +}; + +module.exports = function(app, _config = {}) { + const opts = Object.assign(baseOptions, config, _config); + return new Promise(resolver => { + jsonqlWsServer(opts, app) + .then(io => { + debug('setup completed'); + resolver({ app, io }); + }); + }); +} diff --git a/packages/@jsonql/ws/tests/fixtures/keys/privateKey.pem b/packages/@jsonql/ws/tests/fixtures/keys/privateKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..52ceae92066efead75838933d8bca25eeb9666ac --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/keys/privateKey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDfDqpnh8TceIRuemm8GWM6nvE6KumK/Lq+POrZqghgHpZa5zjv +wwjsJ2iK45zWIRpggMkSlQZWvnRRjj/TWfv7448qhhiTB7hmqV63XjfYXJ5OgTtN +fPW36ZQ48Ha0y4sjlU4gvSijHpnzrJ5yV/vjLLLp9WxTux4ColeZu2B/XQIDAQAB +AoGAEmLJFQOR7IJamCiq8oA9N6XGSH8lBPnUAr5OtWZYjmO3DQMmJE01PRH6gghE +8zmDTRUQfeGexiOovtg01p0CMhehwS8D8d0m01s43zQ77xVJuFAvuW1U1kER4Xze +tVkLEvvO9PcWpKUEmxYpDoCJXGIfXuHaSAVbVLYDKn2MEUECQQD4FeWlpkxSNQT9 +u6w01zR/byjXzUmibOP5zrpaEsDGIxxTlxc/7WJZlKLNybXUyZE8oHgepuefdcL0 +ybk6gvQpAkEA5ixdMtnsbUImJYNFrt5BbLzEU9eF76hovsOSjOc2eTUJHEeiXeDA +Q66WZwXNBf/CRrZdsAvBPMQcWzJLwp24FQJBAPaojtPMLEXwAS5l0ioXblLlqq4l +pfigW2qcaBv2WUSm1BsoNi2RUB/Q8K26x9bxMj4dLlELkW+yHkxT5J6QZUECQFRO +A4TQlOwfwmETB77Y4RW2viIHWqNBB7x3XYIGXclfR4r4IdxIqaMgmy34zfNYjgvg +V8hXRdu/6LLuZRlPM1ECQHUppZNG7WKP9F7ywAr33u3xD0+9MqsfqcgKPfP9VOxs +Lo8EdmjmB30lyyP/Cd1hzxb+BsJjGmxzU/DikGbWos8= +-----END RSA PRIVATE KEY----- diff --git a/packages/@jsonql/ws/tests/fixtures/keys/publicKey.pem b/packages/@jsonql/ws/tests/fixtures/keys/publicKey.pem new file mode 100644 index 0000000000000000000000000000000000000000..7bd2532afbeb5b3be8b9c9f275ffac7b32456d0d --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/keys/publicKey.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfDqpnh8TceIRuemm8GWM6nvE6 +KumK/Lq+POrZqghgHpZa5zjvwwjsJ2iK45zWIRpggMkSlQZWvnRRjj/TWfv7448q +hhiTB7hmqV63XjfYXJ5OgTtNfPW36ZQ48Ha0y4sjlU4gvSijHpnzrJ5yV/vjLLLp +9WxTux4ColeZu2B/XQIDAQAB +-----END PUBLIC KEY----- diff --git a/packages/@jsonql/ws/tests/fixtures/node/index.js b/packages/@jsonql/ws/tests/fixtures/node/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3d6f0446b8b240a89dc38c981c0744c4f40509ac --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/node/index.js @@ -0,0 +1,8 @@ +const clientGenerator = require('../../../src/node/client-generator') +const { chainCreateNsps, es } = require('./test.cjs') + +module.exports = { + clientGenerator, + chainCreateNsps, + es +} diff --git a/packages/@jsonql/ws/tests/fixtures/node/test.cjs.js b/packages/@jsonql/ws/tests/fixtures/node/test.cjs.js new file mode 100644 index 0000000000000000000000000000000000000000..0a8cb3e84de1444f5962e1a9d6930cee7a8466a8 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/node/test.cjs.js @@ -0,0 +1,720 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var debug = _interopDefault(require('debug')); + +/** + * Try to normalize it to use between browser and node + * @param {string} name for the debug output + * @return {function} debug + */ +var getDebug = function (name) { + if (debug) { + return debug('jsonql-ws-client').extend(name) + } + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + console.info.apply(null, [name].concat(args)); + } +}; +try { + if (window && window.localStorage) { + localStorage.setItem('DEBUG', 'jsonql-ws-client*'); + } +} catch(e) {} + +var NB_EVENT_SERVICE_PRIVATE_STORE = new WeakMap(); +var NB_EVENT_SERVICE_PRIVATE_LAZY = new WeakMap(); + +/** + * generate a 32bit hash based on the function.toString() + * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery + * @param {string} s the converted to string function + * @return {string} the hashed function string + */ +function hashCode(s) { + return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0) +} + +// this is the new implementation without the hash key +// export +var EventService = function EventService(config) { + if ( config === void 0 ) config = {}; + + if (config.logger && typeof config.logger === 'function') { + this.logger = config.logger; + } + this.keep = config.keep; + // for the $done setter + this.result = config.keep ? [] : null; + // we need to init the store first otherwise it could be a lot of checking later + this.normalStore = new Map(); + this.lazyStore = new Map(); +}; + +var prototypeAccessors = { $done: { configurable: true },normalStore: { configurable: true },lazyStore: { configurable: true } }; + +/** + * logger function for overwrite + */ +EventService.prototype.logger = function logger () {}; + +////////////////////////// +// PUBLIC METHODS // +////////////////////////// + +/** + * Register your evt handler, note we don't check the type here, + * we expect you to be sensible and know what you are doing. + * @param {string} evt name of event + * @param {function} callback bind method --> if it's array or not + * @param {object} [context=null] to execute this call in + * @return {number} the size of the store + */ +EventService.prototype.$on = function $on (evt , callback , context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + var type = 'on'; + this.validate(evt, callback); + // first need to check if this evt is in lazy store + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register first then call later + if (lazyStoreContent === false) { + this.logger('$on', (evt + " callback is not in lazy store")); + // @TODO we need to check if there was other listener to this + // event and are they the same type then we could solve that + // register the different type to the same event name + + return this.addToNormalStore(evt, type, callback, context) + } + this.logger('$on', (evt + " found in lazy store")); + // this is when they call $trigger before register this callback + var size = 0; + lazyStoreContent.forEach(function (content) { + var payload = content[0]; + var ctx = content[1]; + var t = content[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + size += this$1.addToNormalStore(evt, type, callback, context || ctx); + }); + return size; +}; + +/** + * once only registered it once, there is no overwrite option here + * @NOTE change in v1.3.0 $once can add multiple listeners + * but once the event fired, it will remove this event (see $only) + * @param {string} evt name + * @param {function} callback to execute + * @param {object} [context=null] the handler execute in + * @return {boolean} result + */ +EventService.prototype.$once = function $once (evt , callback , context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'once'; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (lazyStoreContent === false) { + this.logger('$once', (evt + " not in the lazy store")); + // v1.3.0 $once now allow to add multiple listeners + return this.addToNormalStore(evt, type, callback, context) + } else { + // now this is the tricky bit + // there is a potential bug here that cause by the developer + // if they call $trigger first, the lazy won't know it's a once call + // so if in the middle they register any call with the same evt name + // then this $once call will be fucked - add this to the documentation + this.logger('$once', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } +}; + +/** + * This one event can only bind one callbackback + * @param {string} evt event name + * @param {function} callback event handler + * @param {object} [context=null] the context the event handler execute in + * @return {boolean} true bind for first time, false already existed + */ +EventService.prototype.$only = function $only (evt, callback, context) { + var this$1 = this; + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'only'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("$only", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('$only', (evt + " found data in lazy store to execute")); + var list = Array.from(lazyStoreContent); + // $only allow to trigger this multiple time on the single handler + list.forEach( function (l) { + var payload = l[0]; + var ctx = l[1]; + var t = l[2]; + if (t && t !== type) { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this$1.run(callback, payload, context || ctx); + }); + } + return added; +}; + +/** + * $only + $once this is because I found a very subtile bug when we pass a + * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0 + * @param {string} evt event name + * @param {function} callback to call later + * @param {object} [context=null] exeucte context + * @return {void} + */ +EventService.prototype.$onlyOnce = function $onlyOnce (evt, callback, context) { + if ( context === void 0 ) context = null; + + this.validate(evt, callback); + var type = 'onlyOnce'; + var added = false; + var lazyStoreContent = this.takeFromStore(evt); + // this is normal register before call $trigger + var nStore = this.normalStore; + if (!nStore.has(evt)) { + this.logger("$onlyOnce", (evt + " add to store")); + added = this.addToNormalStore(evt, type, callback, context); + } + if (lazyStoreContent !== false) { + // there are data store in lazy store + this.logger('$onlyOnce', lazyStoreContent); + var list = Array.from(lazyStoreContent); + // should never have more than 1 + var ref = list[0]; + var payload = ref[0]; + var ctx = ref[1]; + var t = ref[2]; + if (t && t !== 'onlyOnce') { + throw new Error(("You are trying to register an event already been taken by other type: " + t)) + } + this.run(callback, payload, context || ctx); + // remove this evt from store + this.$off(evt); + } + return added; +}; + +/** + * This is a shorthand of $off + $on added in V1.5.0 + * @param {string} evt event name + * @param {function} callback to exeucte + * @param {object} [context = null] or pass a string as type + * @param {string} [type=on] what type of method to replace + * @return {} + */ +EventService.prototype.$replace = function $replace (evt, callback, context, type) { + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = 'on'; + + if (this.validateType(type)) { + this.$off(evt); + var method = this['$' + type]; + return Reflect.apply(method, this, [evt, callback, context]) + } + throw new Error((type + " is not supported!")) +}; + +/** + * trigger the event + * @param {string} evt name NOT allow array anymore! + * @param {mixed} [payload = []] pass to fn + * @param {object|string} [context = null] overwrite what stored + * @param {string} [type=false] if pass this then we need to add type to store too + * @return {number} if it has been execute how many times + */ +EventService.prototype.$trigger = function $trigger (evt , payload , context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + this.validateEvt(evt); + var found = 0; + // first check the normal store + var nStore = this.normalStore; + this.logger('$trigger', nStore); + if (nStore.has(evt)) { + this.logger('$trigger', evt, 'found'); + var nSet = Array.from(nStore.get(evt)); + var ctn = nSet.length; + var hasOnce = false; + for (var i=0; i < ctn; ++i) { + ++found; + // this.logger('found', found) + var ref = nSet[i]; + var _ = ref[0]; + var callback = ref[1]; + var ctx = ref[2]; + var type$1 = ref[3]; + this.run(callback, payload, context || ctx); + if (type$1 === 'once' || type$1 === 'onlyOnce') { + hasOnce = true; + } + } + if (hasOnce) { + nStore.delete(evt); + } + return found; + } + // now this is not register yet + this.addToLazyStore(evt, payload, context, type); + return found; +}; + +/** + * this is an alias to the $trigger + * @NOTE breaking change in V1.6.0 we swap the parameter around + * @param {string} evt event name + * @param {*} params pass to the callback + * @param {string} type of call + * @param {object} context what context callback execute in + * @return {*} from $trigger + */ +EventService.prototype.$call = function $call (evt, params, type, context) { + if ( type === void 0 ) type = false; + if ( context === void 0 ) context = null; + + var args = [evt, params]; + args.push(context, type); + return Reflect.apply(this.$trigger, this, args) +}; + +/** + * remove the evt from all the stores + * @param {string} evt name + * @return {boolean} true actually delete something + */ +EventService.prototype.$off = function $off (evt) { + this.validateEvt(evt); + var stores = [ this.lazyStore, this.normalStore ]; + var found = false; + stores.forEach(function (store) { + if (store.has(evt)) { + found = true; + store.delete(evt); + } + }); + return found; +}; + +/** + * return all the listener from the event + * @param {string} evtName event name + * @param {boolean} [full=false] if true then return the entire content + * @return {array|boolean} listerner(s) or false when not found + */ +EventService.prototype.$get = function $get (evt, full) { + if ( full === void 0 ) full = false; + + this.validateEvt(evt); + var store = this.normalStore; + if (store.has(evt)) { + return Array + .from(store.get(evt)) + .map( function (l) { + if (full) { + return l; + } + var key = l[0]; + var callback = l[1]; + return callback; + }) + } + return false; +}; + +/** + * store the return result from the run + * @param {*} value whatever return from callback + */ +prototypeAccessors.$done.set = function (value) { + this.logger('set $done', value); + if (this.keep) { + this.result.push(value); + } else { + this.result = value; + } +}; + +/** + * @TODO is there any real use with the keep prop? + * getter for $done + * @return {*} whatever last store result + */ +prototypeAccessors.$done.get = function () { + if (this.keep) { + this.logger(this.result); + return this.result[this.result.length - 1] + } + return this.result; +}; + +///////////////////////////// +// PRIVATE METHODS // +///////////////////////////// + +/** + * validate the event name + * @param {string} evt event name + * @return {boolean} true when OK + */ +EventService.prototype.validateEvt = function validateEvt (evt) { + if (typeof evt === 'string') { + return true; + } + throw new Error("event name must be string type!") +}; + +/** + * Simple quick check on the two main parameters + * @param {string} evt event name + * @param {function} callback function to call + * @return {boolean} true when OK + */ +EventService.prototype.validate = function validate (evt, callback) { + if (this.validateEvt(evt)) { + if (typeof callback === 'function') { + return true; + } + } + throw new Error("callback required to be function type!") +}; + +/** + * Check if this type is correct or not added in V1.5.0 + * @param {string} type for checking + * @return {boolean} true on OK + */ +EventService.prototype.validateType = function validateType (type) { + var types = ['on', 'only', 'once', 'onlyOnce']; + return !!types.filter(function (t) { return type === t; }).length; +}; + +/** + * Run the callback + * @param {function} callback function to execute + * @param {array} payload for callback + * @param {object} ctx context or null + * @return {void} the result store in $done + */ +EventService.prototype.run = function run (callback, payload, ctx) { + this.logger('run', callback, payload, ctx); + this.$done = Reflect.apply(callback, ctx, this.toArray(payload)); +}; + +/** + * Take the content out and remove it from store id by the name + * @param {string} evt event name + * @param {string} [storeName = lazyStore] name of store + * @return {object|boolean} content or false on not found + */ +EventService.prototype.takeFromStore = function takeFromStore (evt, storeName) { + if ( storeName === void 0 ) storeName = 'lazyStore'; + + var store = this[storeName]; // it could be empty at this point + if (store) { + this.logger('takeFromStore', storeName, store); + if (store.has(evt)) { + var content = store.get(evt); + this.logger('takeFromStore', content); + store.delete(evt); + return content; + } + return false; + } + throw new Error((storeName + " is not supported!")) +}; + +/** + * The add to store step is similar so make it generic for resuse + * @param {object} store which store to use + * @param {string} evt event name + * @param {spread} args because the lazy store and normal store store different things + * @return {array} store and the size of the store + */ +EventService.prototype.addToStore = function addToStore (store, evt) { + var args = [], len = arguments.length - 2; + while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ]; + + var fnSet; + if (store.has(evt)) { + this.logger('addToStore', (evt + " existed")); + fnSet = store.get(evt); + } else { + this.logger('addToStore', ("create new Set for " + evt)); + // this is new + fnSet = new Set(); + } + // lazy only store 2 items - this is not the case in V1.6.0 anymore + // we need to check the first parameter is string or not + if (args.length > 2) { + if (Array.isArray(args[0])) { // lazy store + // check if this type of this event already register in the lazy store + var t = args[2]; + if (!this.checkTypeInLazyStore(evt, t)) { + fnSet.add(args); + } + } else { + if (!this.checkContentExist(args, fnSet)) { + this.logger('addToStore', "insert new", args); + fnSet.add(args); + } + } + } else { // add straight to lazy store + fnSet.add(args); + } + store.set(evt, fnSet); + return [store, fnSet.size] +}; + +/** + * @param {array} args for compare + * @param {object} fnSet A Set to search from + * @return {boolean} true on exist + */ +EventService.prototype.checkContentExist = function checkContentExist (args, fnSet) { + var list = Array.from(fnSet); + return !!list.filter(function (l) { + var hash = l[0]; + if (hash === args[0]) { + return true; + } + return false; + }).length; +}; + +/** + * get the existing type to make sure no mix type add to the same store + * @param {string} evtName event name + * @param {string} type the type to check + * @return {boolean} true you can add, false then you can't add this type + */ +EventService.prototype.checkTypeInStore = function checkTypeInStore (evtName, type) { + this.validateEvt(evtName); + this.validateEvt(type); + var all = this.$get(evtName, true); + if (all === false) { + // pristine it means you can add + return true; + } + // it should only have ONE type in ONE event store + return !all.filter(function (list) { + var t = list[3]; + return type !== t; + }).length; +}; + +/** + * This is checking just the lazy store because the structure is different + * therefore we need to use a new method to check it + */ +EventService.prototype.checkTypeInLazyStore = function checkTypeInLazyStore (evtName, type) { + this.validateEvt(evtName); + this.validateEvt(type); + var store = this.lazyStore.get(evtName); + this.logger('checkTypeInLazyStore', store); + if (store) { + return !!Array + .from(store) + .filter(function (l) { + var t = l[2]; + return t !== type; + }).length + } + return false; +}; + +/** + * wrapper to re-use the addToStore, + * V1.3.0 add extra check to see if this type can add to this evt + * @param {string} evt event name + * @param {string} type on or once + * @param {function} callback function + * @param {object} context the context the function execute in or null + * @return {number} size of the store + */ +EventService.prototype.addToNormalStore = function addToNormalStore (evt, type, callback, context) { + if ( context === void 0 ) context = null; + + this.logger('addToNormalStore', evt, type, 'add to normal store'); + // @TODO we need to check the existing store for the type first! + if (this.checkTypeInStore(evt, type)) { + this.logger((type + " can add to " + evt + " store")); + var key = this.hashFnToKey(callback); + var args = [this.normalStore, evt, key, callback, context, type]; + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.normalStore = _store; + return size; + } + return false; +}; + +/** + * Add to lazy store this get calls when the callback is not register yet + * so we only get a payload object or even nothing + * @param {string} evt event name + * @param {array} payload of arguments or empty if there is none + * @param {object} [context=null] the context the callback execute in + * @param {string} [type=false] register a type so no other type can add to this evt + * @return {number} size of the store + */ +EventService.prototype.addToLazyStore = function addToLazyStore (evt, payload, context, type) { + if ( payload === void 0 ) payload = []; + if ( context === void 0 ) context = null; + if ( type === void 0 ) type = false; + + // this is add in V1.6.0 + // when there is type then we will need to check if this already added in lazy store + // and no other type can add to this lazy store + var args = [this.lazyStore, evt, this.toArray(payload), context]; + if (type) { + args.push(type); + } + var ref = Reflect.apply(this.addToStore, this, args); + var _store = ref[0]; + var size = ref[1]; + this.lazyStore = _store; + return size; +}; + +/** + * make sure we store the argument correctly + * @param {*} arg could be array + * @return {array} make sured + */ +EventService.prototype.toArray = function toArray (arg) { + return Array.isArray(arg) ? arg : [arg]; +}; + +/** + * setter to store the Set in private + * @param {object} obj a Set + */ +prototypeAccessors.normalStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj); +}; + +/** + * @return {object} Set object + */ +prototypeAccessors.normalStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_STORE.get(this) +}; + +/** + * setter to store the Set in lazy store + * @param {object} obj a Set + */ +prototypeAccessors.lazyStore.set = function (obj) { + NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj); +}; + +/** + * @return {object} the lazy store Set + */ +prototypeAccessors.lazyStore.get = function () { + return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this) +}; + +/** + * generate a hashKey to identify the function call + * The build-in store some how could store the same values! + * @param {function} fn the converted to string function + * @return {string} hashKey + */ +EventService.prototype.hashFnToKey = function hashFnToKey (fn) { + return hashCode(fn.toString()) + ''; +}; + +Object.defineProperties( EventService.prototype, prototypeAccessors ); + +// default + +// create a clone version so we know which one we actually is using +var JsonqlWsEvt = /*@__PURE__*/(function (NBEventService) { + function JsonqlWsEvt() { + NBEventService.call(this, {logger: getDebug('nb-event-service')}); + } + + if ( NBEventService ) JsonqlWsEvt.__proto__ = NBEventService; + JsonqlWsEvt.prototype = Object.create( NBEventService && NBEventService.prototype ); + JsonqlWsEvt.prototype.constructor = JsonqlWsEvt; + + var prototypeAccessors = { name: { configurable: true } }; + + prototypeAccessors.name.get = function () { + return 'jsonql-ws-client' + }; + + Object.defineProperties( JsonqlWsEvt.prototype, prototypeAccessors ); + + return JsonqlWsEvt; +}(EventService)); + +// break this out for testing purposes +var debugFn = getDebug('chain-create-nsps'); +/** + * previously we already make sure the order of the namespaces + * and attach the auth client to it + * @param {array} promises array of unresolved promises + * @return {object} promise resolved with the array of promises resolved results + */ +function chainCreateNsps(promises) { + return promises.reduce(function (promiseChain, currentTask) { + debugFn('out %O', currentTask); + return promiseChain.then(function (chainResults) { return ( + currentTask.then(function (currentResult) { return ( + chainResults.concat( [currentResult]) + ); }) + ); }) + }, Promise.resolve([])) +} + +// test inteface to figure out what went wrong with the connection + +/// INIT //// +var es = new JsonqlWsEvt({ + logger: debugFn$1 +}); +var debugFn$1 = debug('jsonql-ws-client:test:cjs'); + +exports.chainCreateNsps = chainCreateNsps; +exports.es = es; diff --git a/packages/@jsonql/ws/tests/fixtures/node/test.js b/packages/@jsonql/ws/tests/fixtures/node/test.js new file mode 100644 index 0000000000000000000000000000000000000000..d23876165c43d6be6a66702699fda1989a13e4b5 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/node/test.js @@ -0,0 +1,16 @@ +// test inteface to figure out what went wrong with the connection + +import debug from 'debug' +import ee from '../../../src/utils/ee' +import chainCreateNsps from '../../../src/utils/chain-create-nsps' + +/// INIT //// +const es = new ee({ + logger: debugFn +}) +const debugFn = debug('jsonql-ws-client:test:cjs') + +export { + chainCreateNsps, + es +} diff --git a/packages/@jsonql/ws/tests/fixtures/resolvers/socket/continuous.js b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/continuous.js new file mode 100644 index 0000000000000000000000000000000000000000..3d468bb97fbe076216fde1fa5137f6c2f0b58dc9 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/continuous.js @@ -0,0 +1,21 @@ +// this will keep sending out message until received a terminate call +let timer; +let ctn = 0; +const debug = require('debug')('jsonql-ws-client:socket:continous') +/** + * @param {string} msg a message + * @return {string} a message with timestamp + */ +module.exports = function continuous(msg) { + if (msg === 'terminate') { + return clearInterval(timer) + } + // use the send setter instead + timer = setInterval(() => { + continuous.send = msg + ` [${++ctn}] ${Date.now()}`; + }, 1000); + // return result + return new Promise((resolver) => { + resolver(`start at ${Date.now()}`) + }); +} diff --git a/packages/@jsonql/ws/tests/fixtures/resolvers/socket/public/pinging.js b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/public/pinging.js new file mode 100644 index 0000000000000000000000000000000000000000..2cf0735176ab954756f092e9468dfc55f4d42663 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/public/pinging.js @@ -0,0 +1,22 @@ +// this is a public method always avaialble +let ctn = 0; +/** + * @param {string} msg message + * @return {string} reply message based on your message + */ +module.exports = function pinging(msg) { + if (ctn > 0) { + switch (msg) { + case 'ping': + pinging.send = 'pong'; + case 'pong': + pinging.send = 'ping'; + default: + return; + //pinging.send = 'You lose!'; + } + return; + } + ++ctn; + return 'connection established'; +} diff --git a/packages/@jsonql/ws/tests/fixtures/resolvers/socket/send-extra-msg.js b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/send-extra-msg.js new file mode 100644 index 0000000000000000000000000000000000000000..9144b99adac8272955e4f636174093a38a184604 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/send-extra-msg.js @@ -0,0 +1,12 @@ +// this one will use the property send to send an different message + + +/** + * @param {number} x a number for process + * @return {number} x + ? + */ +module.exports = function sendExtraMsg(x) { + sendExtraMsg.send = x + 2; + + return x + 1; +} diff --git a/packages/@jsonql/ws/tests/fixtures/resolvers/socket/simple.js b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/simple.js new file mode 100644 index 0000000000000000000000000000000000000000..61810eae68ed7c1c7c2442288d62843acdbd873c --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/simple.js @@ -0,0 +1,9 @@ +// just simple send and process + +/** + * @param {number} i a number + * @return {number} a number + 1; + */ +module.exports = function(i) { + return ++i; +} diff --git a/packages/@jsonql/ws/tests/fixtures/resolvers/socket/throw-error.js b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/throw-error.js new file mode 100644 index 0000000000000000000000000000000000000000..a7fcd6f4b4bce70b962a312f7abe1c5025852130 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/resolvers/socket/throw-error.js @@ -0,0 +1,9 @@ +// this one will throw an error + +/** + * Testing the throw error + * @return {error} just throw + */ +module.exports = function() { + throw new Error('Shitty Shitty Bang Bang'); +} diff --git a/packages/@jsonql/ws/tests/fixtures/server-setup.js b/packages/@jsonql/ws/tests/fixtures/server-setup.js new file mode 100644 index 0000000000000000000000000000000000000000..1bb5ef2be4ac691269b8a6aa5204eda82019a855 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/server-setup.js @@ -0,0 +1,37 @@ +const http = require('http') +const fsx = require('fs-extra') +const { join } = require('path') +const debug = require('debug')('jsonql-ws-client:fixtures:server') +const { JSONQL_PATH } = require('jsonql-constants') + +const resolverDir = join(__dirname, 'resolvers') +const contractDir = join(__dirname, 'contract') +// require('../../../ws-server') +const wsServer = require('jsonql-ws-server') + +// start +const server = http.createServer(function(req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }) + res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2)) + res.end() +}) + +module.exports = function(extra = {}) { + // extra.contract = extra.contract || contract; + return new Promise(resolver => { + wsServer( + Object.assign({ + resolverDir, + contractDir, + serverType: 'ws' + }, extra), + server + ) + .then(io => { + resolver({ + io, + app: server + }); + }) + }); +} diff --git a/packages/@jsonql/ws/tests/fixtures/token.js b/packages/@jsonql/ws/tests/fixtures/token.js new file mode 100644 index 0000000000000000000000000000000000000000..b1d444430ce0430ea315ea3e822e7d940f4e0e69 --- /dev/null +++ b/packages/@jsonql/ws/tests/fixtures/token.js @@ -0,0 +1,16 @@ +// generate token + +const { join } = require('path') +const fsx = require('fs-extra') +const privateKey = fsx.readFileSync(join(__dirname, 'keys', 'privateKey.pem')) +const { jwtRsaToken, jwtToken } = require('jsonql-jwt') +const { HSA_ALGO } = require('jsonql-constants') + +module.exports = function(payload, key = false) { + if (key === false) { + return jwtRsaToken(payload, privateKey) + } + return jwtToken(payload, key, { + algorithm: HSA_ALGO + }) +} diff --git a/packages/@jsonql/ws/tests/jwt/ws-handshake.test.js b/packages/@jsonql/ws/tests/jwt/ws-handshake.test.js new file mode 100644 index 0000000000000000000000000000000000000000..9829abfd24134e26a87476b1d1468da033de726a --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/ws-handshake.test.js @@ -0,0 +1,104 @@ +// WS handshake test +const test = require('ava') +const http = require('http') +const WebSocket = require('ws') +const url = require('url') +const fsx = require('fs-extra') +const { join } = require('path') +const debug = require('debug')('jsonql-jwt:test:ws-handshake') + +const { + wsVerifyClient, + jwtRsaToken, + wsNodeClient, + wsNodeAuthClient, + wsGetUserdata +} = require('../main') + +const baseDir = join(__dirname, 'fixtures', 'keys') +const publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) +const privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) + +// set up +const msg = 'Hello there'; +const payload = { name: 'John Doe' }; +const token = jwtRsaToken(payload, privateKey) +const verifyClient = wsVerifyClient(publicKey) +const port = 3006; +const server = http.createServer() +const { JSONQL_PATH, PUBLIC_KEY, PRIVATE_KEY } = require('jsonql-constants') +const namespaces = [ + `/${JSONQL_PATH}/${PUBLIC_KEY}`, + `/${JSONQL_PATH}/${PRIVATE_KEY}` +]; + +// test start +test.before( t => { + const wss = namespaces.map((n, i) => { + if (i > 0) { + return new WebSocket.Server({noServer: true, verifyClient}) + } + return new WebSocket.Server({ noServer: true }) + }) + t.context.wss = wss; + server.on('upgrade', function upgrade(request, socket, head) { + const pathname = url.parse(request.url).pathname; + if (pathname === namespaces[0]) { + wss[0].handleUpgrade(request, socket, head, function done(ws) { + wss[0].emit('connection', ws, request) + }); + } else if (pathname === namespaces[1]) { + wss[1].handleUpgrade(request, socket, head, function done(ws) { + wss[1].emit('connection', ws, request) + }); + } else { + socket.destroy() + } + }); + server.listen(port) + t.context.server = server; +}) + +test.after( t => { + t.context.server.close() +}) + +test.cb(`It should able to connect to the ${namespaces[0]} without token`, t => { + t.plan(1); + t.context.wss[0].on('connection', function connection(ws, request) { + + ws.on('message', function incoming(message) { + t.is(message, msg) + t.end() + }) + }) + // client + let client = wsNodeClient(`ws://localhost:${port}${namespaces[0]}`) + client.on('open', function open() { + client.send(msg) + }) +}) + +test.cb(`It should able to call the verifyClient when trying connect to ${namespaces[1]} with token`, t => { + t.plan(2) + t.context.wss[1].on('connection', function connection(ws, request) { + const userdata = wsGetUserdata(request) + ws.on('message', function incoming(message) { + t.is(message, msg) + ws.send(JSON.stringify(userdata)) + }) + }) + + let client = wsNodeAuthClient(`ws://localhost:${port}${namespaces[1]}`, token); + client.on('open', function open() { + client.send(msg) + }) + + client.on('message', function incoming(data) { + let userdata = JSON.parse(data) + debug('userdata', userdata) + t.truthy(userdata.name) + t.end() + }) + +}) diff --git a/packages/@jsonql/ws/tests/test-node.test.js b/packages/@jsonql/ws/tests/test-node.test.js new file mode 100644 index 0000000000000000000000000000000000000000..af83dde7f3e942ea4f36d31fa8187fd21326f00d --- /dev/null +++ b/packages/@jsonql/ws/tests/test-node.test.js @@ -0,0 +1,204 @@ +/// breaking things apart and try to figure out what went wrong at the last step +const test = require('ava') +const debug = require('debug')('jsonql-ws-client:test:node') +/// SERVER SETUP /// +const { join } = require('path') +const fsx = require('fs-extra') + +const serverSetup = require('./fixtures/server-setup') +const genToken = require('./fixtures/token') + +const contractDir = join(__dirname, 'fixtures', 'contract', 'auth') +const contract = fsx.readJsonSync(join(contractDir, 'contract.json')) +const publicContract = fsx.readJsonSync(join(contractDir, 'public-contract.json')) +const { NOT_LOGIN_ERR_MSG, JS_WS_SOCKET_IO_NAME, JS_WS_NAME } = require('jsonql-constants') +const payload = {name: 'Joel'}; +const token = genToken(payload) +const port = 8010; +const url = `ws://localhost:${port}` +//////////////////// +const { + chainCreateNsps, + clientGenerator, + es +} = require('./fixtures/node') + +/// PREPARE TEST /// +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: true, + keysDir: join(__dirname, 'fixtures', 'keys') + }) + + t.context.server = app.listen(port) + + let config = { opts: { serverType: JS_WS_SOCKET_IO_NAME }, nspMap: {}, ee: es }; + let { opts, ee } = clientGenerator(config) + t.context.opts = opts; + t.context.ee = ee; +}) + +// real test start here +test.serial.cb('It should able to replace the same event with new method', t => { + + t.plan(3) + // try a sequence with swapping out the event handler + let ee = t.context.ee; + let evtName = 'main-event'; + let fnName = 'testFn'; + + ee.$on(evtName, (from, value) => { + debug(evtName, from, value) + // (1) + t.is(from, fnName) + return ++value; + }) + // first trigger it + ee.$call(evtName, [fnName, 1]) + // (2) + t.is(ee.$done, 2) + // now replace this event with another callback + ee.$replace(evtName, (from, value) => { + debug(evtName, from, value) + // (3) + t.is(value, 3) + t.end() + return --value; + }) + ee.$call(evtName, [fnName, 3]) +}) + +test.serial.cb.only('It should able to resolve the promise one after the other', t => { + t.plan(1) + let opts = t.context.opts; + let p1 = () => opts.nspAuthClient([url, 'jsonql/private'].join('/'), token) + let p2 = () => opts.nspClient([url, 'jsonql/public'].join('/')) + /* + let p1 = () => new Promise(resolver => { + setTimeout(() => { + resolver('first') + }, 1000) + }) + let p2 = () => new Promise(resolver => { resolver('second') }) + */ + chainCreateNsps([ + p1(), p2() + ]).then(results => { + debug(results) + t.pass() + t.end() + }) +}) + +test.serial.cb('Just test with the ws client can connect to the server normally', t => { + t.plan(2) + let opts = t.context.opts; + + // t.truthy(opts.nspClient) + // t.truthy(opts.nspAuthClient) + + opts.nspAuthClient([url, 'jsonql/private'].join('/'), token) + .then(socket => { + debug('io1 pass') + t.pass() + opts.nspClient([url, 'jsonql/public'].join('/')) + .then( socket => { + debug('io2 pass') + t.pass() + t.end() + }) + }) + + /* + this was for ws + ws1.onopen = function() { + t.pass() + debug('ws1 connected') + } + ws2.onopen = function() { + t.pass() + debug('ws2 connected') + ws1.terminate() + ws2.terminate() + t.end() + } + */ +}) + + +test.serial.cb('It should able to use the chainCreateNsps to run connection in sequence', t => { + t.plan(1) + let opts = t.context.opts; + + // t.truthy(opts.nspClientAsync) + // t.truthy(opts.nspAuthClientAsync) + + opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token) + .then(ws => { + t.pass() + t.end() + }) + + // the bug is the chainCreateNsps somehow when we put it in there + // the connection just hang + + /* + chainCreateNsps([ + opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token), + // opts.nspClientAsync([url, 'jsonql/public'].join('/')) + ]).then(nsps => { + t.is(nsps.length, 2) + nsps.forEach(nsp => { + nsp.terminate() + }) + t.end() + }) + */ +}) + +test.serial.cb.skip('It should able to wrap the connect call with the onopen callback', t => { + t.plan(3) + let opts = t.context.opts; + let ee = t.context.ee; + let publicConnect = () => { + return opts.nspClientAsync([url, 'jsonql/public'].join('/')) + .then(ws => { + ws.onopen = function() { + ee.$trigger('onReady1', ws) + } + return 'jsonql/public' + }) + } + + let privateConnect = () => { + return opts.nspAuthClientAsync([url, 'jsonql/private'].join('/'), token) + .then(ws => { + ws.onopen = function() { + ee.$trigger('onReady2', ws) + } + return 'jsonql/private' + }) + } + + chainCreateNsps([ + privateConnect(), + publicConnect() + ]).then(namespaces => { + t.is(namespaces.length, 2) + }) + + ee.$on('onReady1', function() { + t.pass() + t.end() + }) + + ee.$on('onReady2', function() { + t.pass() + }) + +}) diff --git a/packages/ws-client/tests/ws-client-auth-login.test.js b/packages/@jsonql/ws/tests/ws-client-auth-login.test.js similarity index 100% rename from packages/ws-client/tests/ws-client-auth-login.test.js rename to packages/@jsonql/ws/tests/ws-client-auth-login.test.js diff --git a/packages/ws-client/tests/ws-client-auth.test.js b/packages/@jsonql/ws/tests/ws-client-auth.test.js similarity index 100% rename from packages/ws-client/tests/ws-client-auth.test.js rename to packages/@jsonql/ws/tests/ws-client-auth.test.js diff --git a/packages/ws-client/tests/ws-client-chain.test.js b/packages/@jsonql/ws/tests/ws-client-chain.test.js similarity index 100% rename from packages/ws-client/tests/ws-client-chain.test.js rename to packages/@jsonql/ws/tests/ws-client-chain.test.js diff --git a/packages/ws-client/tests/ws-client.test.js b/packages/@jsonql/ws/tests/ws-client.test.js similarity index 100% rename from packages/ws-client/tests/ws-client.test.js rename to packages/@jsonql/ws/tests/ws-client.test.js diff --git a/packages/constants/README.md b/packages/constants/README.md index 1bf09ed82d395db0e99611cb5da24fa79f453f0d..0d01a6b919422afec75e9b13a556d124c6c9ecf8 100755 --- a/packages/constants/README.md +++ b/packages/constants/README.md @@ -10,64 +10,129 @@ non-javascript to develop your tool. You can also use the included `constants.js ## constants -```js -// @TODO explain how and where to use them -HELLO, -HELLO_FN, -EXT, -TS_EXT, -INDEX, -DEFAULT_TYPE, -DEFAULT_FILE_NAME, -PUBLIC_FILE_NAME, -QUERY_NAME, -MUTATION_NAME, -SOCKET_NAME, -RESOLVER_TYPES, -API_REQUEST_METHODS, -CONTRACT_REQUEST_METHODS, -CONTENT_TYPE, -KEY_WORD, -PUBLIC_KEY, -TYPE_KEY, -OPTIONAL_KEY, -ENUM_KEY, -ARGS_KEY, -CHECKER_KEY, -AUTH_TYPE, -ISSUER_NAME, -VALIDATOR_NAME, -LOGOUT_NAME, -AUTH_TYPE_METHODS, -AUTH_HEADER, -AUTH_CHECK_HEADER, -BEARER, -JSONQL_PATH, -CREDENTIAL_STORAGE_KEY, -CLIENT_STORAGE_KEY, -CLIENT_AUTH_KEY, -CONTRACT_KEY_NAME, -DEFAULT_RESOLVER_DIR, -DEFAULT_CONTRACT_DIR, -DEFAULT_HEADER, -CLIENT_CONFIG_FILE, -CJS_TYPE, -ES_TYPE, -TS_TYPE, -ACCEPTED_JS_TYPES, -NUMBER_TYPE, -NUMBER_TYPES, -SUPPORTED_TYPES, -NUMBER_TYPE, -STRING_TYPE, -BOOLEAN_TYPE, -ARRAY_TYPE, -OBJECT_TYPE, -ANY_TYPE, -ARRAY_TS_TYPE_LFT, -ARRAY_TYPE_LFT, -ARRAY_TYPE_RGT -``` +- EXT +- TS_EXT +- HELLO +- HELLO_FN +- DATA_KEY +- ERROR_KEY +- JSONQL_PATH +- CONTENT_TYPE +- CHARSET +- DEFAULT_HEADER +- INDEX +- DEFAULT_TYPE +- DEFAULT_CONTRACT_FILE_NAME +- PUBLIC_CONTRACT_FILE_NAME +- DEFAULT_RESOLVER_LIST_FILE_NAME +- DEFAULT_RESOLVER_IMPORT_FILE_NAME +- MODULE_TYPE +- SCRIPT_TYPE +- QUERY_NAME +- MUTATION_NAME +- SOCKET_NAME +- CONTRACT_NAME +- RESOLVER_TYPES +- PAYLOAD_PARAM_NAME +- CONDITION_PARAM_NAME +- RESOLVER_PARAM_NAME +- QUERY_ARG_NAME +- MUTATION_ARGS +- JSONP_CALLBACK_NAME +- API_REQUEST_METHODS +- CONTRACT_REQUEST_METHODS +- KEY_WORD +- PUBLIC_KEY +- PRIVATE_KEY +- TYPE_KEY +- OPTIONAL_KEY +- ENUM_KEY +- ARGS_KEY +- CHECKER_KEY +- ALIAS_KEY +- AUTH_TYPE +- LOGIN_NAME +- ISSUER_NAME +- LOGOUT_NAME +- VALIDATOR_NAME +- AUTH_HEADER +- AUTH_CHECK_HEADER +- BEARER +- CREDENTIAL_STORAGE_KEY +- CLIENT_STORAGE_KEY +- CLIENT_AUTH_KEY +- INDEX_KEY +- CONTRACT_KEY_NAME +- SHOW_CONTRACT_DESC_PARAM +- DEFAULT_RESOLVER_DIR +- DEFAULT_CONTRACT_DIR +- DEFAULT_KEYS_DIR +- CJS_TYPE +- ES_TYPE +- TS_TYPE +- ACCEPTED_JS_TYPES +- OR_SEPERATOR +- STRING_TYPE +- BOOLEAN_TYPE +- ARRAY_TYPE +- OBJECT_TYPE +- ANY_TYPE +- NUMBER_TYPE +- NUMBER_TYPES +- SUPPORTED_TYPES +- ARRAY_TS_TYPE_LFT +- ARRAY_TYPE_LFT +- ARRAY_TYPE_RGT +- RETURN_AS_FILE +- RETURN_AS_JSON +- RETURN_AS_ENUM +- NO_ERROR_MSG +- NO_STATUS_CODE +- SWITCH_USER_EVENT_NAME +- LOGIN_EVENT_NAME +- LOGOUT_EVENT_NAME +- WS_REPLY_TYPE +- WS_EVT_NAME +- WS_DATA_NAME +- WS_IS_REPLY_KEYS +- EMIT_REPLY_TYPE +- ACKNOWLEDGE_REPLY_TYPE +- ERROR_TYPE +- JS_WS_SOCKET_IO_NAME +- JS_WS_NAME +- JS_PRIMUS_NAME +- GO_WS_COOLPY7_NAME +- MESSAGE_PROP_NAME +- RESULT_PROP_NAME +- ERROR_PROP_NAME +- READY_PROP_NAME +- SEND_MSG_PROP_NAME +- DEFAULT_WS_WAIT_TIME +- TIMEOUT_ERR_MSG +- NOT_LOGIN_ERR_MSG +- BASE64_FORMAT +- HEX_FORMAT +- UTF8_FORMAT +- RSA_FORMATS +- RSA_ALGO +- HSA_ALGO +- JWT_SUPPORT_ALGOS +- RSA_PRIVATE_KEY_HEADER +- RSA_MIN_MODULE_LEN +- RSA_MAX_MODULE_LEN +- TOKEN_PARAM_NAME +- IO_ROUNDTRIP_LOGIN +- IO_HANDSHAKE_LOGIN +- IO_LOGIN_METHODS +- PEM_EXT +- PUBLIC_KEY_NAME +- PRIVATE_KEY_NAME +- DEFAULT_PUBLIC_KEY_FILE +- DEFAULT_PRIVATE_KEY_FILE +- SUCCESS_STATUS +- FORBIDDEN_STATUS +- NOT_FOUND_STATUS + --- diff --git a/packages/constants/README_TEMPLATE.md b/packages/constants/README_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..82b1e7649fe5382c9308a10544bbe96d4842692c --- /dev/null +++ b/packages/constants/README_TEMPLATE.md @@ -0,0 +1,19 @@ +[![NPM](https://nodei.co/npm/jsonql-constants.png?compact=true)](https://npmjs.org/package/jsonql-constants) + +# jsonql-constants + +This is a module that just export all the share constant use across all the +[json:ql](https://jsonql.org) tools. + +Use it only when you want to develop your json:ql compatible tool. If you are using +non-javascript to develop your tool. You can also use the included `constants.json`. + +## constants + +[REPLACE] + +--- + +MIT + +to1source / newbran ltd (c) 2019 diff --git a/packages/constants/build.js b/packages/constants/build.js index f98d22bfd0ebe721a9d8a8979f00c9eea48bf3aa..6e01805d91e284061085f47ffb85a0547d8e3b7f 100644 --- a/packages/constants/build.js +++ b/packages/constants/build.js @@ -1,20 +1,31 @@ // turn the js into JSON for other language to use -const fsx = require('fs-extra'); -const { join } = require('path'); -const props = require('./index.js'); +const fsx = require('fs-extra') +const { join } = require('path') +const props = require('./index.js') + +const cjs = `module.exports = ${JSON.stringify(props, null, 4)}` let json = {}; +let readme = ''; for (let key in props) { - console.log(`${key} === ${props[key]}`); + // console.log(`${key} === ${props[key]}`) + readme += `- ${key}\r\n` json[key] = props[key]; } +// create new README +const tpl = fsx.readFileSync(join(__dirname, 'README_TEMPLATE.md')) +const content = tpl.toString().replace('[REPLACE]', readme) + +fsx.outputFileSync(join(__dirname, 'README.md'), content) +fsx.outputFileSync(join(__dirname, 'main.js'), cjs) fsx.outputJson(join(__dirname, 'constants.json'), json, {spaces: 2}, err => { if (err) { - console.log('ERROR:', err); - process.exit(); - return; + console.log('ERROR:', err) + process.exit() + return } - console.log('[ contants.json generated ]'); -}); + + console.log('[ contants.json generated ]') +}) diff --git a/packages/constants/constants.json b/packages/constants/constants.json index 520eabba6cc36d42c534d0a718bf7f4a3d77ae1a..bc04e31955ec1f0fff093ebca47244660cdc8f36 100644 --- a/packages/constants/constants.json +++ b/packages/constants/constants.json @@ -132,6 +132,7 @@ "ERROR_TYPE": "error", "JS_WS_SOCKET_IO_NAME": "socket.io", "JS_WS_NAME": "ws", + "JS_PRIMUS_NAME": "primus", "GO_WS_COOLPY7_NAME": "coolpy7", "MESSAGE_PROP_NAME": "onMessage", "RESULT_PROP_NAME": "onResult", diff --git a/packages/constants/index.js b/packages/constants/index.js index 8dfc9adfc9697332963312ff5b34e37b6735cb72..fbb9234093e5afa791b49fbec8f84fec24fe5cc4 100644 --- a/packages/constants/index.js +++ b/packages/constants/index.js @@ -1,2 +1,2 @@ require = require("esm")(module/*, options*/) -module.exports = require("./main.js") +module.exports = require("./module.js") diff --git a/packages/constants/main.js b/packages/constants/main.js index e68b2023edfef055ae75a6ca57fa9eb56f6658b7..dab22c3e958611f62544da4e4967b6c66d6424b8 100644 --- a/packages/constants/main.js +++ b/packages/constants/main.js @@ -1,174 +1,176 @@ -export const EXT = 'js'; // we might do a ts in the future -export const TS_EXT = 'ts'; - -export const HELLO = 'Hello world!'; -export const HELLO_FN = 'helloWorld'; -// the core stuff to id if it's calling with jsonql -export const DATA_KEY = 'data'; -export const ERROR_KEY = 'error'; - -export const JSONQL_PATH = 'jsonql'; -// according to the json query spec -export const CONTENT_TYPE = 'application/vnd.api+json'; -export const CHARSET = 'charset=utf-8'; -export const DEFAULT_HEADER = { - 'Accept': CONTENT_TYPE, - 'Content-Type': [ CONTENT_TYPE, CHARSET ].join(';') -} - -export const INDEX = 'index'; -export const DEFAULT_TYPE = 'any'; -// contract file names -// export const DEFAULT_FILE_NAME = 'contract.json'; // @TODO remove once all changed -// export const PUBLIC_FILE_NAME = 'public-contract.json'; // @TODO remove once all changed -export const DEFAULT_CONTRACT_FILE_NAME = 'contract.json'; -export const PUBLIC_CONTRACT_FILE_NAME = 'public-contract.json'; -// this is for the ES6 module import and export -export const DEFAULT_RESOLVER_LIST_FILE_NAME = 'resolver.js'; -export const DEFAULT_RESOLVER_IMPORT_FILE_NAME = 'import.js'; -export const MODULE_TYPE = 'module'; -export const SCRIPT_TYPE = 'script'; - -// @TODO remove this is not in use -// export const CLIENT_CONFIG_FILE = '.clients.json'; -// export const CONTRACT_CONFIG_FILE = 'jsonql-contract-config.js'; -// type of resolvers -export const QUERY_NAME = 'query'; -export const MUTATION_NAME = 'mutation'; -export const SOCKET_NAME = 'socket'; -export const CONTRACT_NAME = 'contract'; -export const RESOLVER_TYPES = [QUERY_NAME, MUTATION_NAME, SOCKET_NAME]; -// for calling the mutation -export const PAYLOAD_PARAM_NAME = 'payload'; -export const CONDITION_PARAM_NAME = 'condition'; -export const RESOLVER_PARAM_NAME = 'resolverName'; -export const QUERY_ARG_NAME = 'args'; -export const MUTATION_ARGS = [RESOLVER_PARAM_NAME, PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME]; -// new jsonp -export const JSONP_CALLBACK_NAME = 'jsonqlJsonpCallback'; - -// methods allow -export const API_REQUEST_METHODS = ['POST', 'PUT']; -export const CONTRACT_REQUEST_METHODS = ['GET', 'HEAD']; -// for contract-cli -export const KEY_WORD = 'continue'; -export const PUBLIC_KEY = 'public'; -export const PRIVATE_KEY = 'private'; - -export const TYPE_KEY = 'type'; -export const OPTIONAL_KEY = 'optional'; -export const ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word -export const ARGS_KEY = 'args'; -export const CHECKER_KEY = 'checker'; -export const ALIAS_KEY = 'alias'; -// author -export const AUTH_TYPE = 'auth'; -export const LOGIN_NAME = 'login'; -export const ISSUER_NAME = LOGIN_NAME; // legacy issue need to replace them later -export const LOGOUT_NAME = 'logout'; -export const VALIDATOR_NAME = 'validator'; - -export const AUTH_HEADER = 'Authorization'; -export const AUTH_CHECK_HEADER = 'authorization'; // this is for checking so it must be lowercase -export const BEARER = 'Bearer'; - -// for client use @TODO need to clean this up some of them are not in use -export const CREDENTIAL_STORAGE_KEY = 'credential'; -export const CLIENT_STORAGE_KEY = 'storageKey'; -export const CLIENT_AUTH_KEY = 'authKey'; -// for id the multiple storage engine -export const INDEX_KEY = 'index'; -// contract key -export const CONTRACT_KEY_NAME = 'X-JSONQL-CV-KEY'; -export const SHOW_CONTRACT_DESC_PARAM = {desc: 'y'}; -// directories -export const DEFAULT_RESOLVER_DIR = 'resolvers'; -export const DEFAULT_CONTRACT_DIR = 'contracts'; -export const DEFAULT_KEYS_DIR = 'keys'; -// add in V1.3.4 start supporting socket - -// for validation -export const CJS_TYPE = 'cjs'; -export const ES_TYPE = 'es'; -export const TS_TYPE = 'ts'; -export const ACCEPTED_JS_TYPES = [CJS_TYPE, ES_TYPE, TS_TYPE]; - -export const OR_SEPERATOR = '|'; - -export const STRING_TYPE = 'string'; -export const BOOLEAN_TYPE = 'boolean'; -export const ARRAY_TYPE = 'array'; -export const OBJECT_TYPE = 'object'; -export const ANY_TYPE = 'any'; - -export const NUMBER_TYPE = 'number'; -export const NUMBER_TYPES = ['int', 'integer', 'float', 'double', 'decimal']; -// supported types -export const SUPPORTED_TYPES = [NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE, ARRAY_TYPE, OBJECT_TYPE, ANY_TYPE]; - -export const ARRAY_TS_TYPE_LFT = 'Array<'; -export const ARRAY_TYPE_LFT = 'array.<'; -export const ARRAY_TYPE_RGT = '>'; -// for contract cli -export const RETURN_AS_FILE = 'file'; -export const RETURN_AS_JSON = 'json'; -export const RETURN_AS_ENUM = [RETURN_AS_FILE, RETURN_AS_JSON]; - -export const NO_ERROR_MSG = 'No message'; -export const NO_STATUS_CODE = -1; - -// use throughout the clients -export const SWITCH_USER_EVENT_NAME = '__switch__'; -export const LOGIN_EVENT_NAME = '__login__'; -export const LOGOUT_EVENT_NAME = '__logout__'; - -// for ws servers -export const WS_REPLY_TYPE = '__reply__'; -export const WS_EVT_NAME = '__event__'; -export const WS_DATA_NAME = '__data__'; -export const WS_IS_REPLY_KEYS = [WS_REPLY_TYPE, WS_EVT_NAME, WS_DATA_NAME]; -export const EMIT_REPLY_TYPE = 'emit'; -export const ACKNOWLEDGE_REPLY_TYPE = 'acknowledge'; -export const ERROR_TYPE = 'error'; - -export const JS_WS_SOCKET_IO_NAME = 'socket.io'; -export const JS_WS_NAME = 'ws'; -export const GO_WS_COOLPY7_NAME = 'coolpy7'; - -// for ws client -export const MESSAGE_PROP_NAME = 'onMessage'; -export const RESULT_PROP_NAME = 'onResult'; -export const ERROR_PROP_NAME = 'onError'; -export const READY_PROP_NAME = 'onReady'; -export const SEND_MSG_PROP_NAME = 'send'; -// this is the default time to wait for reply if exceed this then we -// trigger an error --> 5 seconds -export const DEFAULT_WS_WAIT_TIME = 5000; -export const TIMEOUT_ERR_MSG = 'timeout'; -export const NOT_LOGIN_ERR_MSG = 'NOT LOGIN'; -// for crypto operation -export const BASE64_FORMAT = 'base64'; -export const HEX_FORMAT = 'hex'; -export const UTF8_FORMAT = 'utf8'; -export const RSA_FORMATS = [BASE64_FORMAT, HEX_FORMAT]; -export const RSA_ALGO = 'RS256'; -export const HSA_ALGO = 'HS256'; -export const JWT_SUPPORT_ALGOS = [RSA_ALGO, HSA_ALGO]; -export const RSA_PRIVATE_KEY_HEADER = 'BEGIN RSA PRIVATE KEY'; -export const RSA_MIN_MODULE_LEN = 1024; -export const RSA_MAX_MODULE_LEN = 4096; -export const TOKEN_PARAM_NAME = 'token'; -export const IO_ROUNDTRIP_LOGIN = 'roundtip'; -export const IO_HANDSHAKE_LOGIN = 'handshake'; -export const IO_LOGIN_METHODS = [IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN]; - -export const PEM_EXT = 'pem'; -export const PUBLIC_KEY_NAME = 'publicKey'; -export const PRIVATE_KEY_NAME = 'privateKey'; - -export const DEFAULT_PUBLIC_KEY_FILE = [PUBLIC_KEY_NAME, PEM_EXT].join('.') -export const DEFAULT_PRIVATE_KEY_FILE = [PRIVATE_KEY_NAME, PEM_EXT].join('.') - -export const SUCCESS_STATUS = 200; -export const FORBIDDEN_STATUS = 403; -export const NOT_FOUND_STATUS = 404; +module.exports = { + "EXT": "js", + "TS_EXT": "ts", + "HELLO": "Hello world!", + "HELLO_FN": "helloWorld", + "DATA_KEY": "data", + "ERROR_KEY": "error", + "JSONQL_PATH": "jsonql", + "CONTENT_TYPE": "application/vnd.api+json", + "CHARSET": "charset=utf-8", + "DEFAULT_HEADER": { + "Accept": "application/vnd.api+json", + "Content-Type": "application/vnd.api+json;charset=utf-8" + }, + "INDEX": "index", + "DEFAULT_TYPE": "any", + "DEFAULT_CONTRACT_FILE_NAME": "contract.json", + "PUBLIC_CONTRACT_FILE_NAME": "public-contract.json", + "DEFAULT_RESOLVER_LIST_FILE_NAME": "resolver.js", + "DEFAULT_RESOLVER_IMPORT_FILE_NAME": "import.js", + "MODULE_TYPE": "module", + "SCRIPT_TYPE": "script", + "QUERY_NAME": "query", + "MUTATION_NAME": "mutation", + "SOCKET_NAME": "socket", + "CONTRACT_NAME": "contract", + "RESOLVER_TYPES": [ + "query", + "mutation", + "socket" + ], + "PAYLOAD_PARAM_NAME": "payload", + "CONDITION_PARAM_NAME": "condition", + "RESOLVER_PARAM_NAME": "resolverName", + "QUERY_ARG_NAME": "args", + "MUTATION_ARGS": [ + "resolverName", + "payload", + "condition" + ], + "JSONP_CALLBACK_NAME": "jsonqlJsonpCallback", + "API_REQUEST_METHODS": [ + "POST", + "PUT" + ], + "CONTRACT_REQUEST_METHODS": [ + "GET", + "HEAD" + ], + "KEY_WORD": "continue", + "PUBLIC_KEY": "public", + "PRIVATE_KEY": "private", + "TYPE_KEY": "type", + "OPTIONAL_KEY": "optional", + "ENUM_KEY": "enumv", + "ARGS_KEY": "args", + "CHECKER_KEY": "checker", + "ALIAS_KEY": "alias", + "AUTH_TYPE": "auth", + "LOGIN_NAME": "login", + "ISSUER_NAME": "login", + "LOGOUT_NAME": "logout", + "VALIDATOR_NAME": "validator", + "AUTH_HEADER": "Authorization", + "AUTH_CHECK_HEADER": "authorization", + "BEARER": "Bearer", + "CREDENTIAL_STORAGE_KEY": "credential", + "CLIENT_STORAGE_KEY": "storageKey", + "CLIENT_AUTH_KEY": "authKey", + "INDEX_KEY": "index", + "CONTRACT_KEY_NAME": "X-JSONQL-CV-KEY", + "SHOW_CONTRACT_DESC_PARAM": { + "desc": "y" + }, + "DEFAULT_RESOLVER_DIR": "resolvers", + "DEFAULT_CONTRACT_DIR": "contracts", + "DEFAULT_KEYS_DIR": "keys", + "CJS_TYPE": "cjs", + "ES_TYPE": "es", + "TS_TYPE": "ts", + "ACCEPTED_JS_TYPES": [ + "cjs", + "es", + "ts" + ], + "OR_SEPERATOR": "|", + "STRING_TYPE": "string", + "BOOLEAN_TYPE": "boolean", + "ARRAY_TYPE": "array", + "OBJECT_TYPE": "object", + "ANY_TYPE": "any", + "NUMBER_TYPE": "number", + "NUMBER_TYPES": [ + "int", + "integer", + "float", + "double", + "decimal" + ], + "SUPPORTED_TYPES": [ + "number", + "string", + "boolean", + "array", + "object", + "any" + ], + "ARRAY_TS_TYPE_LFT": "Array<", + "ARRAY_TYPE_LFT": "array.<", + "ARRAY_TYPE_RGT": ">", + "RETURN_AS_FILE": "file", + "RETURN_AS_JSON": "json", + "RETURN_AS_ENUM": [ + "file", + "json" + ], + "NO_ERROR_MSG": "No message", + "NO_STATUS_CODE": -1, + "SWITCH_USER_EVENT_NAME": "__switch__", + "LOGIN_EVENT_NAME": "__login__", + "LOGOUT_EVENT_NAME": "__logout__", + "WS_REPLY_TYPE": "__reply__", + "WS_EVT_NAME": "__event__", + "WS_DATA_NAME": "__data__", + "WS_IS_REPLY_KEYS": [ + "__reply__", + "__event__", + "__data__" + ], + "EMIT_REPLY_TYPE": "emit", + "ACKNOWLEDGE_REPLY_TYPE": "acknowledge", + "ERROR_TYPE": "error", + "JS_WS_SOCKET_IO_NAME": "socket.io", + "JS_WS_NAME": "ws", + "JS_PRIMUS_NAME": "primus", + "GO_WS_COOLPY7_NAME": "coolpy7", + "MESSAGE_PROP_NAME": "onMessage", + "RESULT_PROP_NAME": "onResult", + "ERROR_PROP_NAME": "onError", + "READY_PROP_NAME": "onReady", + "SEND_MSG_PROP_NAME": "send", + "DEFAULT_WS_WAIT_TIME": 5000, + "TIMEOUT_ERR_MSG": "timeout", + "NOT_LOGIN_ERR_MSG": "NOT LOGIN", + "BASE64_FORMAT": "base64", + "HEX_FORMAT": "hex", + "UTF8_FORMAT": "utf8", + "RSA_FORMATS": [ + "base64", + "hex" + ], + "RSA_ALGO": "RS256", + "HSA_ALGO": "HS256", + "JWT_SUPPORT_ALGOS": [ + "RS256", + "HS256" + ], + "RSA_PRIVATE_KEY_HEADER": "BEGIN RSA PRIVATE KEY", + "RSA_MIN_MODULE_LEN": 1024, + "RSA_MAX_MODULE_LEN": 4096, + "TOKEN_PARAM_NAME": "token", + "IO_ROUNDTRIP_LOGIN": "roundtip", + "IO_HANDSHAKE_LOGIN": "handshake", + "IO_LOGIN_METHODS": [ + "roundtip", + "handshake" + ], + "PEM_EXT": "pem", + "PUBLIC_KEY_NAME": "publicKey", + "PRIVATE_KEY_NAME": "privateKey", + "DEFAULT_PUBLIC_KEY_FILE": "publicKey.pem", + "DEFAULT_PRIVATE_KEY_FILE": "privateKey.pem", + "SUCCESS_STATUS": 200, + "FORBIDDEN_STATUS": 403, + "NOT_FOUND_STATUS": 404 +} \ No newline at end of file diff --git a/packages/constants/module.js b/packages/constants/module.js new file mode 100644 index 0000000000000000000000000000000000000000..f147e753547bdf240cef84f46d92430a39a58366 --- /dev/null +++ b/packages/constants/module.js @@ -0,0 +1,175 @@ +export const EXT = 'js'; // we might do a ts in the future +export const TS_EXT = 'ts'; + +export const HELLO = 'Hello world!'; +export const HELLO_FN = 'helloWorld'; +// the core stuff to id if it's calling with jsonql +export const DATA_KEY = 'data'; +export const ERROR_KEY = 'error'; + +export const JSONQL_PATH = 'jsonql'; +// according to the json query spec +export const CONTENT_TYPE = 'application/vnd.api+json'; +export const CHARSET = 'charset=utf-8'; +export const DEFAULT_HEADER = { + 'Accept': CONTENT_TYPE, + 'Content-Type': [ CONTENT_TYPE, CHARSET ].join(';') +} + +export const INDEX = 'index'; +export const DEFAULT_TYPE = 'any'; +// contract file names +// export const DEFAULT_FILE_NAME = 'contract.json'; // @TODO remove once all changed +// export const PUBLIC_FILE_NAME = 'public-contract.json'; // @TODO remove once all changed +export const DEFAULT_CONTRACT_FILE_NAME = 'contract.json'; +export const PUBLIC_CONTRACT_FILE_NAME = 'public-contract.json'; +// this is for the ES6 module import and export +export const DEFAULT_RESOLVER_LIST_FILE_NAME = 'resolver.js'; +export const DEFAULT_RESOLVER_IMPORT_FILE_NAME = 'import.js'; +export const MODULE_TYPE = 'module'; +export const SCRIPT_TYPE = 'script'; + +// @TODO remove this is not in use +// export const CLIENT_CONFIG_FILE = '.clients.json'; +// export const CONTRACT_CONFIG_FILE = 'jsonql-contract-config.js'; +// type of resolvers +export const QUERY_NAME = 'query'; +export const MUTATION_NAME = 'mutation'; +export const SOCKET_NAME = 'socket'; +export const CONTRACT_NAME = 'contract'; +export const RESOLVER_TYPES = [QUERY_NAME, MUTATION_NAME, SOCKET_NAME]; +// for calling the mutation +export const PAYLOAD_PARAM_NAME = 'payload'; +export const CONDITION_PARAM_NAME = 'condition'; +export const RESOLVER_PARAM_NAME = 'resolverName'; +export const QUERY_ARG_NAME = 'args'; +export const MUTATION_ARGS = [RESOLVER_PARAM_NAME, PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME]; +// new jsonp +export const JSONP_CALLBACK_NAME = 'jsonqlJsonpCallback'; + +// methods allow +export const API_REQUEST_METHODS = ['POST', 'PUT']; +export const CONTRACT_REQUEST_METHODS = ['GET', 'HEAD']; +// for contract-cli +export const KEY_WORD = 'continue'; +export const PUBLIC_KEY = 'public'; +export const PRIVATE_KEY = 'private'; + +export const TYPE_KEY = 'type'; +export const OPTIONAL_KEY = 'optional'; +export const ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word +export const ARGS_KEY = 'args'; +export const CHECKER_KEY = 'checker'; +export const ALIAS_KEY = 'alias'; +// author +export const AUTH_TYPE = 'auth'; +export const LOGIN_NAME = 'login'; +export const ISSUER_NAME = LOGIN_NAME; // legacy issue need to replace them later +export const LOGOUT_NAME = 'logout'; +export const VALIDATOR_NAME = 'validator'; + +export const AUTH_HEADER = 'Authorization'; +export const AUTH_CHECK_HEADER = 'authorization'; // this is for checking so it must be lowercase +export const BEARER = 'Bearer'; + +// for client use @TODO need to clean this up some of them are not in use +export const CREDENTIAL_STORAGE_KEY = 'credential'; +export const CLIENT_STORAGE_KEY = 'storageKey'; +export const CLIENT_AUTH_KEY = 'authKey'; +// for id the multiple storage engine +export const INDEX_KEY = 'index'; +// contract key +export const CONTRACT_KEY_NAME = 'X-JSONQL-CV-KEY'; +export const SHOW_CONTRACT_DESC_PARAM = {desc: 'y'}; +// directories +export const DEFAULT_RESOLVER_DIR = 'resolvers'; +export const DEFAULT_CONTRACT_DIR = 'contracts'; +export const DEFAULT_KEYS_DIR = 'keys'; +// add in V1.3.4 start supporting socket + +// for validation +export const CJS_TYPE = 'cjs'; +export const ES_TYPE = 'es'; +export const TS_TYPE = 'ts'; +export const ACCEPTED_JS_TYPES = [CJS_TYPE, ES_TYPE, TS_TYPE]; + +export const OR_SEPERATOR = '|'; + +export const STRING_TYPE = 'string'; +export const BOOLEAN_TYPE = 'boolean'; +export const ARRAY_TYPE = 'array'; +export const OBJECT_TYPE = 'object'; +export const ANY_TYPE = 'any'; + +export const NUMBER_TYPE = 'number'; +export const NUMBER_TYPES = ['int', 'integer', 'float', 'double', 'decimal']; +// supported types +export const SUPPORTED_TYPES = [NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE, ARRAY_TYPE, OBJECT_TYPE, ANY_TYPE]; + +export const ARRAY_TS_TYPE_LFT = 'Array<'; +export const ARRAY_TYPE_LFT = 'array.<'; +export const ARRAY_TYPE_RGT = '>'; +// for contract cli +export const RETURN_AS_FILE = 'file'; +export const RETURN_AS_JSON = 'json'; +export const RETURN_AS_ENUM = [RETURN_AS_FILE, RETURN_AS_JSON]; + +export const NO_ERROR_MSG = 'No message'; +export const NO_STATUS_CODE = -1; + +// use throughout the clients +export const SWITCH_USER_EVENT_NAME = '__switch__'; +export const LOGIN_EVENT_NAME = '__login__'; +export const LOGOUT_EVENT_NAME = '__logout__'; + +// for ws servers +export const WS_REPLY_TYPE = '__reply__'; +export const WS_EVT_NAME = '__event__'; +export const WS_DATA_NAME = '__data__'; +export const WS_IS_REPLY_KEYS = [WS_REPLY_TYPE, WS_EVT_NAME, WS_DATA_NAME]; +export const EMIT_REPLY_TYPE = 'emit'; +export const ACKNOWLEDGE_REPLY_TYPE = 'acknowledge'; +export const ERROR_TYPE = 'error'; + +export const JS_WS_SOCKET_IO_NAME = 'socket.io'; +export const JS_WS_NAME = 'ws'; +export const JS_PRIMUS_NAME = 'primus' +export const GO_WS_COOLPY7_NAME = 'coolpy7'; + +// for ws client +export const MESSAGE_PROP_NAME = 'onMessage'; +export const RESULT_PROP_NAME = 'onResult'; +export const ERROR_PROP_NAME = 'onError'; +export const READY_PROP_NAME = 'onReady'; +export const SEND_MSG_PROP_NAME = 'send'; +// this is the default time to wait for reply if exceed this then we +// trigger an error --> 5 seconds +export const DEFAULT_WS_WAIT_TIME = 5000; +export const TIMEOUT_ERR_MSG = 'timeout'; +export const NOT_LOGIN_ERR_MSG = 'NOT LOGIN'; +// for crypto operation +export const BASE64_FORMAT = 'base64'; +export const HEX_FORMAT = 'hex'; +export const UTF8_FORMAT = 'utf8'; +export const RSA_FORMATS = [BASE64_FORMAT, HEX_FORMAT]; +export const RSA_ALGO = 'RS256'; +export const HSA_ALGO = 'HS256'; +export const JWT_SUPPORT_ALGOS = [RSA_ALGO, HSA_ALGO]; +export const RSA_PRIVATE_KEY_HEADER = 'BEGIN RSA PRIVATE KEY'; +export const RSA_MIN_MODULE_LEN = 1024; +export const RSA_MAX_MODULE_LEN = 4096; +export const TOKEN_PARAM_NAME = 'token'; +export const IO_ROUNDTRIP_LOGIN = 'roundtip'; +export const IO_HANDSHAKE_LOGIN = 'handshake'; +export const IO_LOGIN_METHODS = [IO_ROUNDTRIP_LOGIN, IO_HANDSHAKE_LOGIN]; + +export const PEM_EXT = 'pem'; +export const PUBLIC_KEY_NAME = 'publicKey'; +export const PRIVATE_KEY_NAME = 'privateKey'; + +export const DEFAULT_PUBLIC_KEY_FILE = [PUBLIC_KEY_NAME, PEM_EXT].join('.') +export const DEFAULT_PRIVATE_KEY_FILE = [PRIVATE_KEY_NAME, PEM_EXT].join('.') + +export const SUCCESS_STATUS = 200; +export const FORBIDDEN_STATUS = 403; +export const NOT_FOUND_STATUS = 404; diff --git a/packages/constants/package.json b/packages/constants/package.json index c3eaa22713d7451603c7dfe1d377cfcb96bcb1b8..a45f205dd9c81040b14d755a95f1ba740ecc093a 100755 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,15 +1,16 @@ { "name": "jsonql-constants", - "version": "1.8.0", + "version": "1.8.1", "description": "All the share constants for json:ql tools", - "main": "index.js", - "module": "main.js", + "main": "main.js", + "module": "module.js", "files": [ - "index.js", "main.js", + "module.js", "constants.json" ], "scripts": { + "build:cjs": "node -r esm module.js", "build": "node ./build.js" }, "keywords": [ @@ -30,9 +31,8 @@ "url": "https://gitee.com/to1source/jsonql/issues" }, "devDependencies": { - "fs-extra": "^8.1.0" - }, - "dependencies": { + "fs-extra": "^8.1.0", "esm": "^3.2.25" - } + }, + "dependencies": {} } diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index 092067b1abb211cf2eb15b987b93f0d8f86e7e07..e0045bccb7ac99732bf1ce76422e2e6276bc7c10 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1 +1 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlJwt={})}(this,function(t){"use strict";function r(t,r,e){return void 0===e&&(e={}),t.connect(r,e)}var e="type",n="optional",o="enumv",u="args",i="checker",a="alias",c=5e3,f="token",s="roundtip",l="handshake";function p(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];return Promise.resolve(Reflect.apply(r,null,t))}function v(t,e,n,o){void 0===o&&(o={});var u,i=o.timeout||c,a=r(t,e,Object.assign({},o,{query:[f,n].join("=")}));return new Promise(function(t,r){u=setTimeout(function(){r()},i),a.on("connect",function(){console.info("socketIoHandshakeLogin connected"),t(a),clearTimeout(u)})})}var h=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(r,e),r}(Error),d=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(r,e),r}(Error),y=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(r,e),r}(Error),b=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(r,e),r}(Error),g=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return-1},Object.defineProperties(r,e),r}(Error),_=function(t,r,e,n){t.emit("authenticate",{token:r}).on("authenticated",e).on("unauthorized",n)};function j(t,e,n,o){var u=r(t,e);return new Promise(function(t,r){_(u,n,function(){return t(u)},r)})}var m="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},w="object"==typeof m&&m&&m.Object===Object&&m,O="object"==typeof self&&self&&self.Object===Object&&self,k=w||O||Function("return this")(),S=k.Symbol,A=Object.prototype,P=A.hasOwnProperty,E=A.toString,T=S?S.toStringTag:void 0;var x=Object.prototype.toString;var z="[object Null]",C="[object Undefined]",I=S?S.toStringTag:void 0;function M(t){return null==t?void 0===t?C:z:I&&I in Object(t)?function(t){var r=P.call(t,T),e=t[T];try{t[T]=void 0;var n=!0}catch(t){}var o=E.call(t);return n&&(r?t[T]=e:delete t[T]),o}(t):function(t){return x.call(t)}(t)}function N(t){return null!=t&&"object"==typeof t}var R="[object Symbol]";function D(t){return"symbol"==typeof t||N(t)&&M(t)==R}function B(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e0){if(++gt>=ht)return arguments[0]}else gt=0;return bt.apply(void 0,arguments)});function wt(t){return t!=t}function Ot(t,r,e){return r==r?function(t,r,e){for(var n=e-1,o=t.length;++n-1&&t%1==0&&t-1&&t%1==0&&t<=It}function Nt(t){return null!=t&&Mt(t.length)&&!K(t)}var Rt=Object.prototype;function Dt(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||Rt)}var Bt="[object Arguments]";function Ft(t){return N(t)&&M(t)==Bt}var Ut=Object.prototype,Wt=Ut.hasOwnProperty,$t=Ut.propertyIsEnumerable,qt=Ft(function(){return arguments}())?Ft:function(t){return N(t)&&Wt.call(t,"callee")&&!$t.call(t,"callee")};var Lt="object"==typeof t&&t&&!t.nodeType&&t,Vt=Lt&&"object"==typeof module&&module&&!module.nodeType&&module,Jt=Vt&&Vt.exports===Lt?k.Buffer:void 0,Ht=(Jt?Jt.isBuffer:void 0)||function(){return!1},Gt={};Gt["[object Float32Array]"]=Gt["[object Float64Array]"]=Gt["[object Int8Array]"]=Gt["[object Int16Array]"]=Gt["[object Int32Array]"]=Gt["[object Uint8Array]"]=Gt["[object Uint8ClampedArray]"]=Gt["[object Uint16Array]"]=Gt["[object Uint32Array]"]=!0,Gt["[object Arguments]"]=Gt["[object Array]"]=Gt["[object ArrayBuffer]"]=Gt["[object Boolean]"]=Gt["[object DataView]"]=Gt["[object Date]"]=Gt["[object Error]"]=Gt["[object Function]"]=Gt["[object Map]"]=Gt["[object Number]"]=Gt["[object Object]"]=Gt["[object RegExp]"]=Gt["[object Set]"]=Gt["[object String]"]=Gt["[object WeakMap]"]=!1;var Yt="object"==typeof t&&t&&!t.nodeType&&t,Kt=Yt&&"object"==typeof module&&module&&!module.nodeType&&module,Qt=Kt&&Kt.exports===Yt&&w.process,Xt=function(){try{var t=Kt&&Kt.require&&Kt.require("util").types;return t||Qt&&Qt.binding&&Qt.binding("util")}catch(t){}}(),Zt=Xt&&Xt.isTypedArray,tr=Zt?function(t){return function(r){return t(r)}}(Zt):function(t){return N(t)&&Mt(t.length)&&!!Gt[M(t)]},rr=Object.prototype.hasOwnProperty;function er(t,r){var e=F(t),n=!e&&qt(t),o=!e&&!n&&Ht(t),u=!e&&!n&&!o&&tr(t),i=e||n||o||u,a=i?function(t,r){for(var e=-1,n=Array(t);++e-1},mr.prototype.set=function(t,r){var e=this.__data__,n=_r(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this};var wr=ft(k,"Map");function Or(t,r){var e,n,o=t.__data__;return("string"==(n=typeof(e=r))||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?o["string"==typeof r?"string":"hash"]:o.map}function kr(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r=n?t:function(t,r,e){var n=-1,o=t.length;r<0&&(r=-r>o?0:o+r),(e=e>o?o:e)<0&&(e+=o),o=r>e?0:e-r>>>0,r>>>=0;for(var u=Array(o);++na))return!1;var f=u.get(t);if(f&&u.get(r))return f==r;var s=-1,l=!0,p=e&Ie?new xe:void 0;for(u.set(t,r),u.set(r,t);++s1?r[n-1]:void 0,u=n>2?r[2]:void 0;for(o=Nn.length>3&&"function"==typeof o?(n--,o):void 0,u&&function(t,r,e){if(!L(e))return!1;var n=typeof r;return!!("number"==n?Nt(e)&&At(r,e.length):"string"==n&&r in e)&&Et(e[r],t)}(r[0],r[1],u)&&(o=n<3?void 0:o,n=1),t=Object(t);++e-1;);return e}(n,o),function(t,r){for(var e=t.length;e--&&Ot(r,t[e],0)>-1;);return e}(n,o)+1).join("")}function qn(t){return!!F(t)||null!=t&&""!==$n(t)}var Ln=function(t){return!Tn(t)&&!Cn(parseFloat(t))},Vn=function(t){return""!==$n(t)&&Tn(t)},Jn=function(t){return function(t){return!0===t||!1===t||N(t)&&M(t)==xn}(t)},Hn=function(t,r){return void 0===r&&(r=!0),!In(t)&&""!==t&&""!==$n(t)&&(!1===r||!0===r&&!function(t){return null===t}(t))},Gn=e,Yn=n,Kn=o,Qn=u,Xn=i,Zn=a,to="continue",ro=function(t){switch(t){case"number":return Ln;case"string":return Vn;case"boolean":return Jn;default:return Hn}},eo=function(t,r){return void 0===r&&(r=""),!!F(t)&&(""===r||""===$n(r)||!(t.filter(function(t){return!ro(r)(t)}).length>0))},no=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},oo=function(t,r){var e=t.arg;return r.length>1?!e.filter(function(t){return!(r.length>r.filter(function(r){return!ro(r)(t)}).length)}).length:r.length>r.filter(function(t){return!eo(e,t)}).length},uo=function(t,r){if(void 0===r&&(r=null),Lr(t)){if(!r)return!0;if(eo(r))return!r.filter(function(r){var e=t[r.name];return!(r.type.length>r.type.filter(function(t){var r;return!!In(e)||(!1!==(r=no(t))?!oo({arg:e},r):!ro(t)(e))}).length)}).length}return!1},io=function(t,r){var e,n,o,u,i;switch(!0){case"object"===t:return o=(n=r).arg,u=n.param,i=[o],Array.isArray(u.keys)&&u.keys.length&&i.push(u.keys),!uo.apply(null,i);case"array"===t:return!eo(r.arg);case!1!==(e=no(t)):return!oo(r,e);default:return!ro(t)(r.arg)}},ao=function(t,r){return In(t)?!0!==r.optional||In(r.defaultvalue)?null:r.defaultvalue:t},co=function(t,r){var e,n=Object.keys(t);return e=r,!!n.filter(function(t){return t===e}).length},fo=function(t){return!qn(t)};function so(t,r){var e=Un(r,function(t,r){return!t[Zn]});return an(e,{})?t:function(t,r){var e={};return r=_n(r),wn(t,function(t,n,o){Pt(e,r(t,n,o),t)}),e}(t,function(t,r){return function(t,r,e){var n;return e(t,function(t,e,o){if(r(t,e,o))return n=e,!1}),n}(e,_n(function(t){return t.alias===r}),wn)||r})}function lo(t,r){return Mn(r,function(r,e){var n,o;return In(t[e])||!0===r[Yn]&&fo(t[e])?Rn({},r,((n={})[to]=!0,n)):((o={})[Qn]=t[e],o[Gn]=r[Gn],o[Yn]=r[Yn]||!1,o[Kn]=r[Kn]||!1,o[Xn]=r[Xn]||!1,o)})}function po(t,r){var e=function(t,r){var e=so(t,r);return{pristineValues:Mn(Un(r,function(t,r){return co(e,r)}),function(t){return t.args}),checkAgainstAppProps:Un(r,function(t,r){return!co(e,r)}),config:e}}(t,r),n=e.config,o=e.pristineValues;return[lo(n,e.checkAgainstAppProps),o]}var vo=function(t){return eo(t)?t:[t]};var ho=function(t,r){return!eo(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},yo=function(t,r){try{return!!K(r)&&r.apply(null,[t])}catch(t){return!1}};function bo(t){return function(r,e){if(r[to])return r[Qn];var n=function(t,r){var e,n=[[t[Qn]],[(e={},e[Gn]=vo(t[Gn]),e[Yn]=t[Yn],e)]];return Reflect.apply(r,null,n)}(r,t);if(n.length)throw new d(e,n);if(!1!==r[Kn]&&!ho(r[Qn],r[Kn]))throw new h(e);if(!1!==r[Xn]&&!yo(r[Qn],r[Xn]))throw new y(e);return r[Qn]}}function go(t,r,e,n){return void 0===t&&(t={}),Rn(function(t,r){var e=t[0],n=t[1],o=Mn(e,bo(r));return Rn(o,n)}(po(t,r),n),e)}var _o=uo,jo=Vn,mo=function(t,r,c){void 0===c&&(c={});var f=c[n],s=c[o],l=c[i],p=c[a];return function(t,r,c,f,s,l){void 0===c&&(c=!1),void 0===f&&(f=!1),void 0===s&&(s=!1),void 0===l&&(l=!1);var p={};return p[u]=t,p[e]=r,!0===c&&(p[n]=!0),eo(f)&&(p[o]=f),K(s)&&(p[i]=s),Tn(l)&&(p[a]=l),p}.apply(null,[t,r,f,s,l,p])},wo=function(t){return function(r,e,n){return void 0===n&&(n={}),go(r,e,n,t)}}(function(t,r,e){var n;void 0===e&&(e=!1);var o=function(t,r){if(!eo(r))throw new g("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!eo(t))throw new g("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==r.length:return t.map(function(t,e){return{arg:t,index:e,param:r[e]}});case!0===r[0].variable:var e=r[0].type;return t.map(function(t,n){return{arg:t,index:n,param:r[n]||{type:e,name:"_"}}});case t.lengthr.length&&1===r.length:var n,o=["any"];return!1!==(n=no(r[0].type[0]))&&(o=n),t.map(function(t,e){return{arg:t,index:e,param:r[e]||{type:o,name:"_"}}});default:throw new g("Could not understand your arguments and parameter structure!",{args:t,params:r})}}(t,r),u=o.filter(function(t){return!0===t.param.optional?function(t){var r=t.arg,e=t.param;return!!qn(r)&&!(e.type.length>e.type.filter(function(r){return io(r,t)}).length)}(t):!(t.param.type.length>t.param.type.filter(function(r){return io(r,t)}).length)});return e?((n={}).error=u,n.data=o.map(function(t){return t.arg}),n):u}),Oo=co;var ko="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function So(t){this.message=t}So.prototype=new Error,So.prototype.name="InvalidCharacterError";var Ao="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var r=String(t).replace(/=+$/,"");if(r.length%4==1)throw new So("'atob' failed: The string to be decoded is not correctly encoded.");for(var e,n,o=0,u=0,i="";n=r.charAt(u++);~n&&(e=o%4?64*e+n:n,o++%4)?i+=String.fromCharCode(255&e>>(-2*o&6)):0)n=ko.indexOf(n);return i};var Po=function(t){var r=t.replace(/-/g,"+").replace(/_/g,"/");switch(r.length%4){case 0:break;case 2:r+="==";break;case 3:r+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(Ao(t).replace(/(.)/g,function(t,r){var e=r.charCodeAt(0).toString(16).toUpperCase();return e.length<2&&(e="0"+e),"%"+e}))}(r)}catch(t){return Ao(r)}};function Eo(t){this.message=t}Eo.prototype=new Error,Eo.prototype.name="InvalidTokenError";var To,xo,zo,Co,Io,Mo,No,Ro,Do,Bo=function(t,r){if("string"!=typeof t)throw new Eo("Invalid token specified");var e=!0===(r=r||{}).header?0:1;try{return JSON.parse(Po(t.split(".")[e]))}catch(t){throw new Eo("Invalid token specified: "+t.message)}},Fo=Eo;Bo.InvalidTokenError=Fo;var Uo={algorithm:mo("HS256",["string"]),expiresIn:mo(!1,["boolean","number","string"],(To={},To[a]="exp",To[n]=!0,To)),notBefore:mo(!1,["boolean","number","string"],(xo={},xo[a]="nbf",xo[n]=!0,xo)),audience:mo(!1,["boolean","string"],(zo={},zo[a]="iss",zo[n]=!0,zo)),subject:mo(!1,["boolean","string"],(Co={},Co[a]="sub",Co[n]=!0,Co)),issuer:mo(!1,["boolean","string"],(Io={},Io[a]="iss",Io[n]=!0,Io)),noTimestamp:mo(!1,["boolean"],(Mo={},Mo[n]=!0,Mo)),header:mo(!1,["boolean","string"],(No={},No[n]=!0,No)),keyid:mo(!1,["boolean","string"],(Ro={},Ro[n]=!0,Ro)),mutatePayload:mo(!1,["boolean"],(Do={},Do[n]=!0,Do))};var Wo=function(){switch(!0){case"undefined"!=typeof WebSocket:return WebSocket;case"undefined"!=typeof MozWebSocket:return MozWebSocket;case"undefined"!=typeof window:return window.WebSocket||window.MozWebSocket;default:throw new b("WebSocket is NOT SUPPORTED!")}}();function $o(t){return new Wo(t)}t.chainPromises=function(t){return t.reduce(function(t,r){return t.then(function(t){return r.then(function(r){return t.concat([r])})})},Promise.resolve([]))},t.decodeToken=function(t){if(jo(t))return function(t){var r=t.iat||Math.floor(Date.now()/1e3);if(t.exp&&r>=t.exp){var e=new Date(t.exp).toISOString();throw new g("Token has expired on "+e,t)}return t}(Bo(t));throw new g("Token must be a string!")},t.groupByNamespace=function(t){var r,e=function(t){return Oo(t,"socket")?t.socket:t}(t),n={},o=0;for(var u in e){var i=e[u],a=i.namespace;a&&(n[a]||(++o,n[a]={}),n[a][u]=i,r||i.public&&(r=a))}return{size:o,nspSet:n,publicNamespace:r}},t.socketIoChainConnect=function(t,r,e,n,o,u){return void 0===o&&(o=l),new Promise(function(u,i){var a=[r,e[0]].join("");Reflect.apply(function(t){switch(console.info("client type: ",t),t){case s:return j;case l:return v;default:throw new b("socketIoChainConnect",{message:"Unknown "+t+" of client!"})}}(o),null,[t,a,n]).then(function(n){var o=[r,e[1]].join("");Reflect.apply(p,null,[t,o]).then(function(t){u([n,t])}).catch(function(t){i({message:"failed on "+o,error:t})})}).catch(function(t){i({message:"failed on "+a,error:t})})})},t.socketIoClient=r,t.socketIoClientAsync=p,t.socketIoHandshakeLogin=v,t.socketIoRoundtripLogin=j,t.tokenValidator=function(t){if(!_o(t))return{};var r={},e=wo(t,Uo);for(var n in e)e[n]&&(r[n]=e[n]);return r},t.wsAuthClient=function(t,r){return $o(t+"?"+f+"="+r)},t.wsClient=$o,Object.defineProperty(t,"__esModule",{value:!0})}); +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlJwt={},t.debug)}(this,function(t,r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function n(t){this.message=t}n.prototype=new Error,n.prototype.name="InvalidCharacterError";var o="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var r=String(t).replace(/=+$/,"");if(r.length%4==1)throw new n("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,i,u=0,a=0,f="";i=r.charAt(a++);~i&&(o=u%4?64*o+i:i,u++%4)?f+=String.fromCharCode(255&o>>(-2*u&6)):0)i=e.indexOf(i);return f};var i=function(t){var r=t.replace(/-/g,"+").replace(/_/g,"/");switch(r.length%4){case 0:break;case 2:r+="==";break;case 3:r+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(o(t).replace(/(.)/g,function(t,r){var e=r.charCodeAt(0).toString(16).toUpperCase();return e.length<2&&(e="0"+e),"%"+e}))}(r)}catch(t){return o(r)}};function u(t){this.message=t}u.prototype=new Error,u.prototype.name="InvalidTokenError";var a=function(t,r){if("string"!=typeof t)throw new u("Invalid token specified");var e=!0===(r=r||{}).header?0:1;try{return JSON.parse(i(t.split(".")[e]))}catch(t){throw new u("Invalid token specified: "+t.message)}},f=u;a.InvalidTokenError=f;var c="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},s="object"==typeof c&&c&&c.Object===Object&&c,h="object"==typeof self&&self&&self.Object===Object&&self,l=s||h||Function("return this")(),p=l.Symbol,v=Object.prototype,g=v.hasOwnProperty,y=v.toString,d=p?p.toStringTag:void 0;var b=Object.prototype.toString;var w="[object Null]",_="[object Undefined]",m=p?p.toStringTag:void 0;function j(t){return null==t?void 0===t?_:w:m&&m in Object(t)?function(t){var r=g.call(t,d),e=t[d];try{t[d]=void 0;var n=!0}catch(t){}var o=y.call(t);return n&&(r?t[d]=e:delete t[d]),o}(t):function(t){return b.call(t)}(t)}function A(t){return null!=t&&"object"==typeof t}var E="[object Symbol]";function O(t){return"symbol"==typeof t||A(t)&&j(t)==E}function P(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e0){if(++ut>=et)return arguments[0]}else ut=0;return it.apply(void 0,arguments)});function st(t){return t!=t}function ht(t,r,e){return r==r?function(t,r,e){for(var n=e-1,o=t.length;++n-1&&t%1==0&&t-1&&t%1==0&&t<=mt}function At(t){return null!=t&&jt(t.length)&&!D(t)}var Et=Object.prototype;function Ot(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||Et)}var Pt="[object Arguments]";function Rt(t){return A(t)&&j(t)==Pt}var Tt=Object.prototype,St=Tt.hasOwnProperty,Ut=Tt.propertyIsEnumerable,Bt=Rt(function(){return arguments}())?Rt:function(t){return A(t)&&St.call(t,"callee")&&!Ut.call(t,"callee")};var kt="object"==typeof t&&t&&!t.nodeType&&t,It=kt&&"object"==typeof module&&module&&!module.nodeType&&module,xt=It&&It.exports===kt?l.Buffer:void 0,Ct=(xt?xt.isBuffer:void 0)||function(){return!1},Yt={};Yt["[object Float32Array]"]=Yt["[object Float64Array]"]=Yt["[object Int8Array]"]=Yt["[object Int16Array]"]=Yt["[object Int32Array]"]=Yt["[object Uint8Array]"]=Yt["[object Uint8ClampedArray]"]=Yt["[object Uint16Array]"]=Yt["[object Uint32Array]"]=!0,Yt["[object Arguments]"]=Yt["[object Array]"]=Yt["[object ArrayBuffer]"]=Yt["[object Boolean]"]=Yt["[object DataView]"]=Yt["[object Date]"]=Yt["[object Error]"]=Yt["[object Function]"]=Yt["[object Map]"]=Yt["[object Number]"]=Yt["[object Object]"]=Yt["[object RegExp]"]=Yt["[object Set]"]=Yt["[object String]"]=Yt["[object WeakMap]"]=!1;var Mt="object"==typeof t&&t&&!t.nodeType&&t,Dt=Mt&&"object"==typeof module&&module&&!module.nodeType&&module,Lt=Dt&&Dt.exports===Mt&&s.process,zt=function(){try{var t=Dt&&Dt.require&&Dt.require("util").types;return t||Lt&&Lt.binding&&Lt.binding("util")}catch(t){}}(),Nt=zt&&zt.isTypedArray,Ft=Nt?function(t){return function(r){return t(r)}}(Nt):function(t){return A(t)&&jt(t.length)&&!!Yt[j(t)]},Vt=Object.prototype.hasOwnProperty;function $t(t,r){var e=R(t),n=!e&&Bt(t),o=!e&&!n&&Ct(t),i=!e&&!n&&!o&&Ft(t),u=e||n||o||i,a=u?function(t,r){for(var e=-1,n=Array(t);++e-1},cr.prototype.set=function(t,r){var e=this.__data__,n=ar(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this};var sr=K(l,"Map");function hr(t,r){var e,n,o=t.__data__;return("string"==(n=typeof(e=r))||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?o["string"==typeof r?"string":"hash"]:o.map}function lr(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r=n?t:function(t,r,e){var n=-1,o=t.length;r<0&&(r=-r>o?0:o+r),(e=e>o?o:e)<0&&(e+=o),o=r>e?0:e-r>>>0,r>>>=0;for(var i=Array(o);++na))return!1;var c=i.get(t);if(c&&i.get(r))return c==r;var s=-1,h=!0,l=e&me?new be:void 0;for(i.set(t,r),i.set(r,t);++s1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=An.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!k(e))return!1;var n=typeof r;return!!("number"==n?At(e)&&vt(r,e.length):"string"==n&&r in e)&&yt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++e-1;);return e}(n,o),function(t,r){for(var e=t.length;e--&&ht(r,t[e],0)>-1;);return e}(n,o)+1).join("")}function Bn(t){return!!R(t)||null!=t&&""!==Un(t)}var kn=function(t){return!dn(t)&&!_n(parseFloat(t))},In=function(t){return""!==Un(t)&&dn(t)},xn=function(t){return function(t){return!0===t||!1===t||A(t)&&j(t)==bn}(t)},Cn=function(t,r){return void 0===r&&(r=!0),!mn(t)&&""!==t&&""!==Un(t)&&(!1===r||!0===r&&!function(t){return null===t}(t))},Yn="type",Mn="optional",Dn="enumv",Ln="args",zn="checker",Nn="alias",Fn=Yn,Vn=Mn,$n=Dn,qn=Ln,Jn=zn,Wn=Nn,Gn="continue",Hn=function(t){switch(t){case"number":return kn;case"string":return In;case"boolean":return xn;default:return Cn}},Zn=function(t,r){return void 0===r&&(r=""),!!R(t)&&(""===r||""===Un(r)||!(t.filter(function(t){return!Hn(r)(t)}).length>0))},Kn=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},Qn=function(t,r){var e=t.arg;return r.length>1?!e.filter(function(t){return!(r.length>r.filter(function(r){return!Hn(r)(t)}).length)}).length:r.length>r.filter(function(t){return!Zn(e,t)}).length},Xn=function(t,r){if(void 0===r&&(r=null),kr(t)){if(!r)return!0;if(Zn(r))return!r.filter(function(r){var e=t[r.name];return!(r.type.length>r.type.filter(function(t){var r;return!!mn(e)||(!1!==(r=Kn(t))?!Qn({arg:e},r):!Hn(t)(e))}).length)}).length}return!1},to=function(){try{if(window||document)return!0}catch(t){}return!1},ro=function(){try{if(!to()&&c)return!0}catch(t){}return!1};var eo=function(t){function r(){for(var r=[],e=arguments.length;e--;)r[e]=arguments[e];t.apply(this,r)}return t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r,r.where=function(){return to()?"browser":ro()?"node":"unknown"},r}(Error),no=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(r,e),r}(Error),oo=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(r,e),r}(Error),io=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,t.captureStackTrace&&t.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(r,e),r}(Error),uo=function(t){function r(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=r.name,Error.captureStackTrace&&Error.captureStackTrace(this,r)}t&&(r.__proto__=t),r.prototype=Object.create(t&&t.prototype),r.prototype.constructor=r;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return-1},Object.defineProperties(r,e),r}(eo);function ao(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}var fo=function(t,r){var e,n,o,i,u;switch(!0){case"object"===t:return o=(n=r).arg,i=n.param,u=[o],Array.isArray(i.keys)&&i.keys.length&&u.push(i.keys),!Xn.apply(null,u);case"array"===t:return!Zn(r.arg);case!1!==(e=Kn(t)):return!Qn(r,e);default:return!Hn(t)(r.arg)}},co=function(t,r){return mn(t)?!0!==r.optional||mn(r.defaultvalue)?null:r.defaultvalue:t},so=function(t,r){var e,n=Object.keys(t);return e=r,!!n.filter(function(t){return t===e}).length},ho=function(t){return!Bn(t)};function lo(t,r){var e=Tn(r,function(t,r){return!t[Wn]});return Ge(e,{})?t:function(t,r){var e={};return r=an(r),sn(t,function(t,n,o){gt(e,r(t,n,o),t)}),e}(t,function(t,r){return function(t,r,e){var n;return e(t,function(t,e,o){if(r(t,e,o))return n=e,!1}),n}(e,an(function(t){return t.alias===r}),sn)||r})}function po(t,r){return jn(r,function(r,e){var n,o;return mn(t[e])||!0===r[Vn]&&ho(t[e])?En({},r,((n={})[Gn]=!0,n)):((o={})[qn]=t[e],o[Fn]=r[Fn],o[Vn]=r[Vn]||!1,o[$n]=r[$n]||!1,o[Jn]=r[Jn]||!1,o)})}function vo(t,r){var e=function(t,r){var e=lo(t,r);return{pristineValues:jn(Tn(r,function(t,r){return so(e,r)}),function(t){return t.args}),checkAgainstAppProps:Tn(r,function(t,r){return!so(e,r)}),config:e}}(t,r),n=e.config,o=e.pristineValues;return[po(n,e.checkAgainstAppProps),o]}var go=function(t){return Zn(t)?t:[t]};var yo=function(t,r){return!Zn(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},bo=function(t,r){try{return!!D(r)&&r.apply(null,[t])}catch(t){return!1}};function wo(t){return function(r,e){if(r[Gn])return r[qn];var n=function(t,r){var e,n=[[t[qn]],[(e={},e[Fn]=go(t[Fn]),e[Vn]=t[Vn],e)]];return Reflect.apply(r,null,n)}(r,t);if(n.length)throw ao("runValidationAction",e,r),new oo(e,n);if(!1!==r[$n]&&!yo(r[qn],r[$n]))throw ao($n,r[$n]),new no(e);if(!1!==r[Jn]&&!bo(r[qn],r[Jn]))throw ao(Jn,r[Jn]),new io(e);return r[qn]}}function _o(t,r,e,n){return void 0===t&&(t={}),En(function(t,r){var e=t[0],n=t[1],o=jn(e,wo(r));return En(o,n)}(vo(t,r),n),e)}function mo(t,r,e,n,o,i){void 0===e&&(e=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===i&&(i=!1);var u={};return u[Ln]=t,u[Yn]=r,!0===e&&(u[Mn]=!0),Zn(n)&&(u[Dn]=n),D(o)&&(u[zn]=o),dn(i)&&(u[Nn]=i),u}var jo=Xn,Ao=In,Eo=function(t,r,e){void 0===e&&(e={});var n=e[Mn],o=e[Dn],i=e[zn],u=e[Nn];return mo.apply(null,[t,r,n,o,i,u])},Oo=function(t){return function(r,e,n){return void 0===n&&(n={}),_o(r,e,n,t)}}(function(t,r,e){var n;void 0===e&&(e=!1);var o=function(t,r){if(!Zn(r))throw new uo("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!Zn(t))throw new uo("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case t.length==r.length:return ao(1),t.map(function(t,e){return{arg:t,index:e,param:r[e]}});case!0===r[0].variable:ao(2);var e=r[0].type;return t.map(function(t,n){return{arg:t,index:n,param:r[n]||{type:e,name:"_"}}});case t.lengthr.length:ao(4);var n=r.length,o=["any"];return t.map(function(t,e){var i=e>=n||!!r[e].optional,u=r[e]||{type:o,name:"_"+e};return{arg:i?co(t,u):t,index:e,param:u,optional:i}});default:throw ao(5),new uo("Could not understand your arguments and parameter structure!",{args:t,params:r})}}(t,r),i=o.filter(function(t){return!0===t.optional||!0===t.param.optional?function(t){var r=t.arg,e=t.param;return!!Bn(r)&&!(e.type.length>e.type.filter(function(r){return fo(r,t)}).length)}(t):!(t.param.type.length>t.param.type.filter(function(r){return fo(r,t)}).length)});return e?((n={}).error=i,n.data=o.map(function(t){return t.arg}),n):i}),Po=function(t){void 0===t&&(t=!1);var r=Date.now();return t?Math.floor(r/1e3):r},Ro=[],To=[],So="undefined"!=typeof Uint8Array?Uint8Array:Array,Uo=!1;function Bo(){Uo=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,e=t.length;r>18&63]+Ro[o>>12&63]+Ro[o>>6&63]+Ro[63&o]);return i.join("")}function Io(t){var r;Uo||Bo();for(var e=t.length,n=e%3,o="",i=[],u=0,a=e-n;ua?a:u+16383));return 1===n?(r=t[e-1],o+=Ro[r>>2],o+=Ro[r<<4&63],o+="=="):2===n&&(r=(t[e-2]<<8)+t[e-1],o+=Ro[r>>10],o+=Ro[r>>4&63],o+=Ro[r<<2&63],o+="="),i.push(o),i.join("")}function xo(t,r,e,n,o){var i,u,a=8*o-n-1,f=(1<>1,s=-7,h=e?o-1:0,l=e?-1:1,p=t[r+h];for(h+=l,i=p&(1<<-s)-1,p>>=-s,s+=a;s>0;i=256*i+t[r+h],h+=l,s-=8);for(u=i&(1<<-s)-1,i>>=-s,s+=n;s>0;u=256*u+t[r+h],h+=l,s-=8);if(0===i)i=1-c;else{if(i===f)return u?NaN:1/0*(p?-1:1);u+=Math.pow(2,n),i-=c}return(p?-1:1)*u*Math.pow(2,i-n)}function Co(t,r,e,n,o,i){var u,a,f,c=8*i-o-1,s=(1<>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:i-1,v=n?1:-1,g=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,u=s):(u=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-u))<1&&(u--,f*=2),(r+=u+h>=1?l/f:l*Math.pow(2,1-h))*f>=2&&(u++,f/=2),u+h>=s?(a=0,u=s):u+h>=1?(a=(r*f-1)*Math.pow(2,o),u+=h):(a=r*Math.pow(2,h-1)*Math.pow(2,o),u=0));o>=8;t[e+p]=255&a,p+=v,a/=256,o-=8);for(u=u<0;t[e+p]=255&u,p+=v,u/=256,c-=8);t[e+p-v]|=128*g}var Yo={}.toString,Mo=Array.isArray||function(t){return"[object Array]"==Yo.call(t)};function Do(){return zo.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function Lo(t,r){if(Do()=Do())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+Do().toString(16)+" bytes");return 0|t}function Jo(t){return!(null==t||!t._isBuffer)}function Wo(t,r){if(Jo(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var e=t.length;if(0===e)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return _i(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return mi(t).length;default:if(n)return _i(t).length;r=(""+r).toLowerCase(),n=!0}}function Go(t,r,e){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(r>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return ci(this,r,e);case"utf8":case"utf-8":return ii(this,r,e);case"ascii":return ai(this,r,e);case"latin1":case"binary":return fi(this,r,e);case"base64":return oi(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return si(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function Ho(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function Zo(t,r,e,n,o){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=o?0:t.length-1),e<0&&(e=t.length+e),e>=t.length){if(o)return-1;e=t.length-1}else if(e<0){if(!o)return-1;e=0}if("string"==typeof r&&(r=zo.from(r,n)),Jo(r))return 0===r.length?-1:Ko(t,r,e,n,o);if("number"==typeof r)return r&=255,zo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):Ko(t,[r],e,n,o);throw new TypeError("val must be string, number or Buffer")}function Ko(t,r,e,n,o){var i,u=1,a=t.length,f=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||r.length<2)return-1;u=2,a/=2,f/=2,e/=2}function c(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(o){var s=-1;for(i=e;ia&&(e=a-f),i=e;i>=0;i--){for(var h=!0,l=0;lo&&(n=o):n=o;var i=r.length;if(i%2!=0)throw new TypeError("Invalid hex string");n>i/2&&(n=i/2);for(var u=0;u>8,o=e%256,i.push(o),i.push(n);return i}(r,t.length-e),t,e,n)}function oi(t,r,e){return 0===r&&e===t.length?Io(t):Io(t.slice(r,e))}function ii(t,r,e){e=Math.min(t.length,e);for(var n=[],o=r;o239?4:c>223?3:c>191?2:1;if(o+h<=e)switch(h){case 1:c<128&&(s=c);break;case 2:128==(192&(i=t[o+1]))&&(f=(31&c)<<6|63&i)>127&&(s=f);break;case 3:i=t[o+1],u=t[o+2],128==(192&i)&&128==(192&u)&&(f=(15&c)<<12|(63&i)<<6|63&u)>2047&&(f<55296||f>57343)&&(s=f);break;case 4:i=t[o+1],u=t[o+2],a=t[o+3],128==(192&i)&&128==(192&u)&&128==(192&a)&&(f=(15&c)<<18|(63&i)<<12|(63&u)<<6|63&a)>65535&&f<1114112&&(s=f)}null===s?(s=65533,h=1):s>65535&&(s-=65536,n.push(s>>>10&1023|55296),s=56320|1023&s),n.push(s),o+=h}return function(t){var r=t.length;if(r<=ui)return String.fromCharCode.apply(String,t);var e="",n=0;for(;n0&&(t=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(t+=" ... ")),""},zo.prototype.compare=function(t,r,e,n,o){if(!Jo(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===e&&(e=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),r<0||e>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&r>=e)return 0;if(n>=o)return-1;if(r>=e)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(n>>>=0),u=(e>>>=0)-(r>>>=0),a=Math.min(i,u),f=this.slice(n,o),c=t.slice(r,e),s=0;so)&&(e=o),t.length>0&&(e<0||r<0)||r>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return Qo(this,t,r,e);case"utf8":case"utf-8":return Xo(this,t,r,e);case"ascii":return ti(this,t,r,e);case"latin1":case"binary":return ri(this,t,r,e);case"base64":return ei(this,t,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ni(this,t,r,e);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},zo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ui=4096;function ai(t,r,e){var n="";e=Math.min(t.length,e);for(var o=r;on)&&(e=n);for(var o="",i=r;ie)throw new RangeError("Trying to access beyond buffer length")}function li(t,r,e,n,o,i){if(!Jo(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>o||rt.length)throw new RangeError("Index out of range")}function pi(t,r,e,n){r<0&&(r=65535+r+1);for(var o=0,i=Math.min(t.length-e,2);o>>8*(n?o:1-o)}function vi(t,r,e,n){r<0&&(r=4294967295+r+1);for(var o=0,i=Math.min(t.length-e,4);o>>8*(n?o:3-o)&255}function gi(t,r,e,n,o,i){if(e+n>t.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function yi(t,r,e,n,o){return o||gi(t,0,e,4),Co(t,r,e,n,23,4),e+4}function di(t,r,e,n,o){return o||gi(t,0,e,8),Co(t,r,e,n,52,8),e+8}zo.prototype.slice=function(t,r){var e,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(r=void 0===r?n:~~r)<0?(r+=n)<0&&(r=0):r>n&&(r=n),r0&&(o*=256);)n+=this[t+--r]*o;return n},zo.prototype.readUInt8=function(t,r){return r||hi(t,1,this.length),this[t]},zo.prototype.readUInt16LE=function(t,r){return r||hi(t,2,this.length),this[t]|this[t+1]<<8},zo.prototype.readUInt16BE=function(t,r){return r||hi(t,2,this.length),this[t]<<8|this[t+1]},zo.prototype.readUInt32LE=function(t,r){return r||hi(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},zo.prototype.readUInt32BE=function(t,r){return r||hi(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},zo.prototype.readIntLE=function(t,r,e){t|=0,r|=0,e||hi(t,r,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*r)),n},zo.prototype.readIntBE=function(t,r,e){t|=0,r|=0,e||hi(t,r,this.length);for(var n=r,o=1,i=this[t+--n];n>0&&(o*=256);)i+=this[t+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*r)),i},zo.prototype.readInt8=function(t,r){return r||hi(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},zo.prototype.readInt16LE=function(t,r){r||hi(t,2,this.length);var e=this[t]|this[t+1]<<8;return 32768&e?4294901760|e:e},zo.prototype.readInt16BE=function(t,r){r||hi(t,2,this.length);var e=this[t+1]|this[t]<<8;return 32768&e?4294901760|e:e},zo.prototype.readInt32LE=function(t,r){return r||hi(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},zo.prototype.readInt32BE=function(t,r){return r||hi(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},zo.prototype.readFloatLE=function(t,r){return r||hi(t,4,this.length),xo(this,t,!0,23,4)},zo.prototype.readFloatBE=function(t,r){return r||hi(t,4,this.length),xo(this,t,!1,23,4)},zo.prototype.readDoubleLE=function(t,r){return r||hi(t,8,this.length),xo(this,t,!0,52,8)},zo.prototype.readDoubleBE=function(t,r){return r||hi(t,8,this.length),xo(this,t,!1,52,8)},zo.prototype.writeUIntLE=function(t,r,e,n){(t=+t,r|=0,e|=0,n)||li(this,t,r,e,Math.pow(2,8*e)-1,0);var o=1,i=0;for(this[r]=255&t;++i=0&&(i*=256);)this[r+o]=t/i&255;return r+e},zo.prototype.writeUInt8=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,1,255,0),zo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[r]=255&t,r+1},zo.prototype.writeUInt16LE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,2,65535,0),zo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):pi(this,t,r,!0),r+2},zo.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,2,65535,0),zo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):pi(this,t,r,!1),r+2},zo.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,4,4294967295,0),zo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):vi(this,t,r,!0),r+4},zo.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,4,4294967295,0),zo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):vi(this,t,r,!1),r+4},zo.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);li(this,t,r,e,o-1,-o)}var i=0,u=1,a=0;for(this[r]=255&t;++i>0)-a&255;return r+e},zo.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);li(this,t,r,e,o-1,-o)}var i=e-1,u=1,a=0;for(this[r+i]=255&t;--i>=0&&(u*=256);)t<0&&0===a&&0!==this[r+i+1]&&(a=1),this[r+i]=(t/u>>0)-a&255;return r+e},zo.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,1,127,-128),zo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},zo.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,2,32767,-32768),zo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):pi(this,t,r,!0),r+2},zo.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,2,32767,-32768),zo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):pi(this,t,r,!1),r+2},zo.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,4,2147483647,-2147483648),zo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):vi(this,t,r,!0),r+4},zo.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||li(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),zo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):vi(this,t,r,!1),r+4},zo.prototype.writeFloatLE=function(t,r,e){return yi(this,t,r,!0,e)},zo.prototype.writeFloatBE=function(t,r,e){return yi(this,t,r,!1,e)},zo.prototype.writeDoubleLE=function(t,r,e){return di(this,t,r,!0,e)},zo.prototype.writeDoubleBE=function(t,r,e){return di(this,t,r,!1,e)},zo.prototype.copy=function(t,r,e,n){if(e||(e=0),n||0===n||(n=this.length),r>=t.length&&(r=t.length),r||(r=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-r=0;--o)t[o+r]=this[o+e];else if(i<1e3||!zo.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,e=void 0===e?this.length:e>>>0,t||(t=0),"number"==typeof t)for(i=r;i55295&&e<57344){if(!o){if(e>56319){(r-=3)>-1&&i.push(239,191,189);continue}if(u+1===n){(r-=3)>-1&&i.push(239,191,189);continue}o=e;continue}if(e<56320){(r-=3)>-1&&i.push(239,191,189),o=e;continue}e=65536+(o-55296<<10|e-56320)}else o&&(r-=3)>-1&&i.push(239,191,189);if(o=null,e<128){if((r-=1)<0)break;i.push(e)}else if(e<2048){if((r-=2)<0)break;i.push(e>>6|192,63&e|128)}else if(e<65536){if((r-=3)<0)break;i.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;i.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return i}function mi(t){return function(t){var r,e,n,o,i,u;Uo||Bo();var a=t.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");i="="===t[a-2]?2:"="===t[a-1]?1:0,u=new So(3*a/4-i),n=i>0?a-4:a;var f=0;for(r=0,e=0;r>16&255,u[f++]=o>>8&255,u[f++]=255&o;return 2===i?(o=To[t.charCodeAt(r)]<<2|To[t.charCodeAt(r+1)]>>4,u[f++]=255&o):1===i&&(o=To[t.charCodeAt(r)]<<10|To[t.charCodeAt(r+1)]<<4|To[t.charCodeAt(r+2)]>>2,u[f++]=o>>8&255,u[f++]=255&o),u}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(bi,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function ji(t,r,e,n){for(var o=0;o=r.length||o>=t.length);++o)r[o+e]=t[o];return o}function Ai(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}c.setTimeout,c.clearTimeout;var Ei,Oi,Pi,Ri,Ti,Si,Ui,Bi,ki,Ii=c.performance||{};Ii.now||Ii.mozNow||Ii.msNow||Ii.oNow||Ii.webkitNow;var xi={algorithm:Eo("HS256",["string"]),expiresIn:Eo(!1,["boolean","number","string"],(Ei={},Ei[Nn]="exp",Ei[Mn]=!0,Ei)),notBefore:Eo(!1,["boolean","number","string"],(Oi={},Oi[Nn]="nbf",Oi[Mn]=!0,Oi)),audience:Eo(!1,["boolean","string"],(Pi={},Pi[Nn]="iss",Pi[Mn]=!0,Pi)),subject:Eo(!1,["boolean","string"],(Ri={},Ri[Nn]="sub",Ri[Mn]=!0,Ri)),issuer:Eo(!1,["boolean","string"],(Ti={},Ti[Nn]="iss",Ti[Mn]=!0,Ti)),noTimestamp:Eo(!1,["boolean"],(Si={},Si[Mn]=!0,Si)),header:Eo(!1,["boolean","string"],(Ui={},Ui[Mn]=!0,Ui)),keyid:Eo(!1,["boolean","string"],(Bi={},Bi[Mn]=!0,Bi)),mutatePayload:Eo(!1,["boolean"],(ki={},ki[Mn]=!0,ki))};t.decodeToken=function(t){if(Ao(t))return function(t){var r=t.iat||Po();if(t.exp&&r>=t.exp){var e=new Date(t.exp).toISOString();throw new uo("Token has expired on "+e,t)}return t}(a(t));throw new uo("Token must be a string!")},t.tokenValidator=function(t){if(!jo(t))return{};var r={},e=Oo(t,xi);for(var n in e)e[n]&&(r[n]=e[n]);return r},Object.defineProperty(t,"__esModule",{value:!0})}); diff --git a/packages/jwt/index.js b/packages/jwt/index.js index ef8a1efa269929d3393754a70d78beb89bc1ed33..a26151c2da348aba9e1f6bd6e18690eb3ab69170 100644 --- a/packages/jwt/index.js +++ b/packages/jwt/index.js @@ -1,33 +1,10 @@ // main export interface for client side modules import { - socketIoClient, - socketIoClientAsync, - socketIoHandshakeLogin, - socketIoRoundtripLogin, - socketIoChainConnect, - decodeToken, - tokenValidator, - - wsAuthClient, - wsClient -} from './src/client'; - -import { groupByNamespace, chainPromises } from './src/client/utils' + tokenValidator +} from './src/client' export { - socketIoClient, - socketIoClientAsync, - socketIoHandshakeLogin, - socketIoRoundtripLogin, - socketIoChainConnect, - decodeToken, - tokenValidator, - - wsAuthClient, - wsClient, - - groupByNamespace, - chainPromises + tokenValidator } diff --git a/packages/jwt/main.js b/packages/jwt/main.js index 355cd9bb266e709bee7b5a4f7cafcc155efcdefb..fe48fdf270a79e5f28599aed353cfdab3b20b782 100644 --- a/packages/jwt/main.js +++ b/packages/jwt/main.js @@ -1,26 +1,16 @@ // main export interface for node modules // import export -const rsaKeys = require('./src/crypto/rsa-keys'); -const rsaPemKeys = require('./src/crypto/rsa-pem-keys'); +const rsaKeys = require('./src/crypto/rsa-keys') +const rsaPemKeys = require('./src/crypto/rsa-pem-keys') // const shaKey = require('./crypto/shaKey'); -const jwtToken = require('./src/jwt/jwt-token'); -const jwtDecode = require('./src/jwt/jwt-decode'); -const jwtRsaToken = require('./src/jwt/jwt-rsa-token'); +const jwtToken = require('./src/jwt/jwt-token') +const jwtDecode = require('./src/jwt/jwt-decode') +const jwtRsaToken = require('./src/jwt/jwt-rsa-token') -const { decodeToken, tokenValidator } = require('./src/jwt/decode-token'); +const { decodeToken, tokenValidator } = require('./src/jwt/decode-token') const { encryptWithPublicPem, decryptWithPrivatePem } = require('./src/crypto/encrypt-decrypt') -const { groupByNamespace, chainPromises } = require('./src/helpers/client-utils') - -// socket.io & ws server side methods const { - socketIoGetUserdata, - socketIoJwtAuth, - socketIoHandshakeAuth, - - wsVerifyClient, - wsGetUserdata, - loginResultToJwt, provideUserdata, createTokenValidator @@ -35,14 +25,6 @@ module.exports = { rsaPemKeys, - socketIoGetUserdata, - socketIoJwtAuth, - socketIoHandshakeAuth, - - wsVerifyClient, - - wsGetUserdata, - loginResultToJwt, provideUserdata, createTokenValidator, @@ -51,8 +33,5 @@ module.exports = { tokenValidator, encryptWithPublicPem, - decryptWithPrivatePem, - - groupByNamespace, - chainPromises + decryptWithPrivatePem } diff --git a/packages/jwt/package.json b/packages/jwt/package.json index 02ebc5d53b74e3be4f63ff6a158b0ef58b7453eb..e3553311d5c26a33a3dd1ef58851f0946d134cb0 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,19 +1,16 @@ { "name": "jsonql-jwt", - "version": "1.2.5", - "description": "jwt authentication helpers library for jsonql", + "version": "1.3.0", + "description": "jwt authentication helpers library for jsonql browser / node", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-jwt.js", "scripts": { - "test": "npm run build:clients && npm run test:run", + "test": "npm run build && npm run test:run", "test:run": "DEBUG=jsonql-jwt* ava", - "build": "npm run build:clients && npm run build:main", + "build": "npm run build:decode && npm run build:main", "build:main": "rollup -c", - "build:clients": "npm run build:io-client && npm run build:decode && npm run build:client-utils", "build:decode": "rollup -c ./rollup.decode-jwt.config.js", - "build:client-utils": "rollup -c ./rollup.client-utils.config.js", - "build:io-client": "rollup -c ./rollup.socket-io-client.config.js", "cmd": "DEBUG=jsonql-jwt* node ./cmd.js", "test:chain-hs": "npm run build:clients && DEBUG=jsonql-jwt*,socket* ava ./tests/socketio-chain-connect-hs.test.js", "test:chain-rt": "npm run build:clients && DEBUG=jsonql-jwt* ava ./tests/socketio-chain-connect-rt.test.js", @@ -49,13 +46,14 @@ "dependencies": { "colors": "^1.3.3", "fs-extra": "^8.1.0", - "jsonql-constants": "^1.7.9", - "jsonql-errors": "^1.1.0", - "jsonql-params-validator": "^1.4.3", + "jsonql-constants": "^1.8.0", + "jsonql-errors": "^1.1.2", + "jsonql-params-validator": "^1.4.4", + "jsonql-utils": "^0.3.14", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", - "yargs": "^13.3.0" + "yargs": "^14.0.0" }, "bin": { "jsonql-jwt": "./cmd.js" @@ -63,16 +61,16 @@ "devDependencies": { "socket.io-client": "^2.2.0", "ws": "^7.1.2", - "ava": "^2.2.0", + "ava": "^2.3.0", "debug": "^4.1.1", "esm": "^3.2.25", - "koa": "^2.7.0", - "rollup": "^1.19.4", - "rollup-plugin-alias": "^1.5.2", + "koa": "^2.8.1", + "rollup": "^1.20.3", + "rollup-plugin-alias": "^2.0.0", "rollup-plugin-async": "^1.2.0", "rollup-plugin-buble": "^0.19.8", "rollup-plugin-bundle-size": "^1.0.3", - "rollup-plugin-commonjs": "^10.0.2", + "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-copy": "^3.1.0", "rollup-plugin-json": "^4.0.0", "rollup-plugin-node-builtins": "^2.1.2", diff --git a/packages/jwt/rollup.config.js b/packages/jwt/rollup.config.js index e13d498b8194cd6fc6b433918e45b5ac1e0f4186..3400f01acb35f40adaf0a7ed6d5594f5167a54e1 100644 --- a/packages/jwt/rollup.config.js +++ b/packages/jwt/rollup.config.js @@ -28,7 +28,7 @@ let plugins = [ buble({ objectAssign: 'Object.assign' }), - nodeResolve(), + nodeResolve({ preferBuiltins: true }), commonjs({ include: 'node_modules/**' }), diff --git a/packages/jwt/rollup.decode-jwt.config.js b/packages/jwt/rollup.decode-jwt.config.js index f2280fe2a87a8419ccd500a121f8322b5899f3fa..e7921eec2e3bd7a0eef8144e3ca13e265d521010 100644 --- a/packages/jwt/rollup.decode-jwt.config.js +++ b/packages/jwt/rollup.decode-jwt.config.js @@ -28,7 +28,7 @@ let plugins = [ buble({ objectAssign: 'Object.assign' }), - nodeResolve(), + nodeResolve({ preferBuiltins: true }), commonjs({ include: 'node_modules/**' }), diff --git a/packages/jwt/src/client/decode-token/decode-token.js b/packages/jwt/src/client/decode-token/decode-token.js index 30774d0269fb3be7b6bdaaa3bf40f6d41be27536..3c92b0bf807f4b3e4a382029a8c7e7da5e6846a2 100644 --- a/packages/jwt/src/client/decode-token/decode-token.js +++ b/packages/jwt/src/client/decode-token/decode-token.js @@ -5,14 +5,14 @@ import jwt_decode from 'jwt-decode' import { isString } from 'jsonql-params-validator' import { JsonqlError } from 'jsonql-errors' - +import { timestamp } from 'jsonql-utils' /** * We only check the nbf and exp * @param {object} token for checking * @return {object} token on success */ function validate(token) { - const start = token.iat || Math.floor(Date.now() / 1000) + const start = token.iat || timestamp() // we only check the exp for the time being if (token.exp) { if (start >= token.exp) { diff --git a/packages/jwt/src/client/index.js b/packages/jwt/src/client/index.js index a67ef0354dd1301c3c1e21dab80882306488a98a..75892232e458505acdbe9097ca279d04d104888f 100644 --- a/packages/jwt/src/client/index.js +++ b/packages/jwt/src/client/index.js @@ -1,5 +1,5 @@ // this is the client side code interface using ES6 - +/* moved to @jsonql/socketio import { socketIoClient, socketIoClientAsync, @@ -7,21 +7,18 @@ import { socketIoRoundtripLogin, socketIoChainConnect } from './socketio' - -import { decodeToken, tokenValidator } from './decode-token' +*/ // ws +/* +moved to @jsonql/ws import { wsAuthClient, wsClient } from './ws/auth-client' +*/ +import { decodeToken, tokenValidator } from './decode-token' + export { - socketIoClient, - socketIoClientAsync, - socketIoHandshakeLogin, - socketIoRoundtripLogin, - socketIoChainConnect, decodeToken, - tokenValidator, + tokenValidator - wsAuthClient, - wsClient } diff --git a/packages/jwt/src/client/utils/chain-promises.js b/packages/jwt/src/client/utils/chain-promises.js deleted file mode 100644 index 56dd0128b13ccda33721294b149b252d1a1b03cd..0000000000000000000000000000000000000000 --- a/packages/jwt/src/client/utils/chain-promises.js +++ /dev/null @@ -1,17 +0,0 @@ -// This is ported back from ws-client -// the idea if from https://decembersoft.com/posts/promises-in-serial-with-array-reduce/ -/** - * previously we already make sure the order of the namespaces - * and attach the auth client to it - * @param {array} promises array of unresolved promises - * @return {object} promise resolved with the array of promises resolved results - */ -export default function chainPromises(promises) { - return promises.reduce((promiseChain, currentTask) => ( - promiseChain.then(chainResults => ( - currentTask.then(currentResult => ( - [...chainResults, currentResult] - )) - )) - ), Promise.resolve([])) -} diff --git a/packages/jwt/src/client/utils/group-by-namespace.js b/packages/jwt/src/client/utils/group-by-namespace.js deleted file mode 100644 index 0c3b340a05a2cb6267d9fe3b67ba6a70a785a5fa..0000000000000000000000000000000000000000 --- a/packages/jwt/src/client/utils/group-by-namespace.js +++ /dev/null @@ -1,42 +0,0 @@ -// This is ported back from ws-server and it will get use in the server / client side -import { isKeyInObject } from 'jsonql-params-validator' - -function extractSocketPart(contract) { - if (isKeyInObject(contract, 'socket')) { - return contract.socket; - } - return contract; -} - -/** - * @BUG we should check the socket part instead of expect the downstream to read the menu! - * We only need this when the enableAuth is true otherwise there is only one namespace - * @param {object} contract the socket part of the contract file - * @return {object} 1. remap the contract using the namespace --> resolvers - * 2. the size of the object (1 all private, 2 mixed public with private) - * 3. which namespace is public - */ -export default function groupByNamespace(contract) { - let socket = extractSocketPart(contract) - - let nspSet = {}; - let size = 0; - let publicNamespace; - for (let resolverName in socket) { - let params = socket[resolverName]; - let { namespace } = params; - if (namespace) { - if (!nspSet[namespace]) { - ++size; - nspSet[namespace] = {}; - } - nspSet[namespace][resolverName] = params; - if (!publicNamespace) { - if (params.public) { - publicNamespace = namespace; - } - } - } - } - return { size, nspSet, publicNamespace } -} diff --git a/packages/jwt/src/client/utils/index.js b/packages/jwt/src/client/utils/index.js deleted file mode 100644 index eb5898e67d56298552cbd5e36ab896a41f86f3c8..0000000000000000000000000000000000000000 --- a/packages/jwt/src/client/utils/index.js +++ /dev/null @@ -1,8 +0,0 @@ -// utils exports -import groupByNamespace from './group-by-namespace' -import chainPromises from './chain-promises' - -export { - groupByNamespace, - chainPromises -} diff --git a/packages/jwt/src/crypto/encrypt-decrypt.js b/packages/jwt/src/crypto/encrypt-decrypt.js index 2cf607ed44a27ea24cd682fe589c599b7f8c9345..1c4555a36e9611fb21713e3514786045f18fbb4b 100644 --- a/packages/jwt/src/crypto/encrypt-decrypt.js +++ b/packages/jwt/src/crypto/encrypt-decrypt.js @@ -1,7 +1,7 @@ const crypto = require('crypto') const path = require('path') const fs = require('fs-extra') -const { BASE64_FORMAT, UTF8_FORMAT } = require('jsonql-constants'); +const { BASE64_FORMAT, UTF8_FORMAT } = require('jsonql-constants') /** * @param {*} toEncrypt data to encypt diff --git a/packages/jwt/src/crypto/rsa-keys.js b/packages/jwt/src/crypto/rsa-keys.js index 9df050e8feca522db399886e884e757d4e13bab6..c591a73f38b1e4c6d39e0e08634bcf8d932a0bea 100644 --- a/packages/jwt/src/crypto/rsa-keys.js +++ b/packages/jwt/src/crypto/rsa-keys.js @@ -1,15 +1,17 @@ -const crypto = require('crypto'); -const primeLength = 60; -const { BASE64_FORMAT, HEX_FORMAT, RSA_FORMATS } = require('jsonql-constants'); -const { inArray } = require('jsonql-params-validator'); -const { JsonqlError } = require('jsonql-errors'); +const crypto = require('crypto') +const { BASE64_FORMAT, HEX_FORMAT, RSA_FORMATS } = require('jsonql-constants') +const { inArray } = require('jsonql-params-validator') +const { JsonqlError } = require('jsonql-errors') + +const PRIME_LENGTH = 60; + /** * create RSA public / private key pair * @param {string} [format=BASE64_FORMAT] what format of key - * @param {number} [len=primeLength] prime length - * @return {object} + * @param {number} [len=PRIME_LENGTH] prime length + * @return {object} publicKey, privateKey */ -module.exports = function rsaKeys(format=BASE64_FORMAT, len = primeLength) { +module.exports = function rsaKeys(format = BASE64_FORMAT, len = PRIME_LENGTH) { if (len > 0 && inArray(RSA_FORMATS, format)) { const diffHell = crypto.createDiffieHellman(len); diffHell.generateKeys(format); diff --git a/packages/jwt/src/crypto/rsa-pem-keys.js b/packages/jwt/src/crypto/rsa-pem-keys.js index a01989b3bb1b6e58692c480d48cb94c633b38e62..0ac647f78231833de41fc3c283fe1d2174a94eac 100644 --- a/packages/jwt/src/crypto/rsa-pem-keys.js +++ b/packages/jwt/src/crypto/rsa-pem-keys.js @@ -1,16 +1,16 @@ - -const { generateKeyPair } = require('crypto'); -const fsx = require('fs-extra'); -const { join, resolve } = require('path'); -const colors = require('colors/safe'); +// generate the pem style keys +const { generateKeyPair } = require('crypto') +const fsx = require('fs-extra') +const { join, resolve } = require('path') +const colors = require('colors/safe') const { PEM_EXT, RSA_MIN_MODULE_LEN, RSA_MAX_MODULE_LEN, DEFAULT_PRIVATE_KEY_FILE, DEFAULT_PUBLIC_KEY_FILE -} = require('jsonql-constants'); -const { JsonqlValidationError, JsonqlError } = require('jsonql-errors'); +} = require('jsonql-constants') +const { JsonqlValidationError, JsonqlError } = require('jsonql-errors') /** * Double check the input len * @param {number} len modulusLength @@ -30,7 +30,7 @@ const checkLen = len => { return len; } } - throw new JsonqlValidationError(`modulusLength needs to be squre by 2 and larger or equal to ${RSA_MIN_MODULE_LEN} and less than or equal to ${RSA_MAX_MODULE_LEN}`); + throw new JsonqlValidationError(`modulusLength needs to be squre by 2 and larger or equal to ${RSA_MIN_MODULE_LEN} and less than or equal to ${RSA_MAX_MODULE_LEN}`) } /** @@ -61,11 +61,11 @@ const outputToDir = (outputDir, result) => { }) ).then(result => { if (files.length === result.length) { - console.info(colors.green(`pem files written to ${dir}`)); + console.info(colors.green(`pem files written to ${dir}`)) // we need to return an object instead of array - return result.reduce((next, last) => Object.assign(next, last), {}); + return result.reduce((next, last) => Object.assign(next, last), {}) } - throw new JsonqlError('Something went wrong, some of the file are not written!', { files, result }); + throw new JsonqlError('Something went wrong, some of the file are not written!', { files, result }) }) .catch(err => { console.error(`[rsa-pem-keys] an error occuried!`, err) @@ -94,10 +94,10 @@ function rsaPemKeysAction(len) { if (err) { return rejecter(err); } - resolver({ publicKey, privateKey }); - }); - }); -}; + resolver({ publicKey, privateKey }) + }) + }) +} /** * Wrap two steps into one with different parameters to control it @@ -107,5 +107,5 @@ function rsaPemKeysAction(len) { */ module.exports = function rsaPemKeys(len = RSA_MIN_MODULE_LEN, outputDir = '') { return rsaPemKeysAction(len) - .then(result => outputDir ? outputToDir(outputDir, result) : result); + .then(result => outputDir ? outputToDir(outputDir, result) : result) } diff --git a/packages/jwt/src/crypto/sha-key.js b/packages/jwt/src/crypto/sha-key.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/packages/jwt/src/helpers/base64.js b/packages/jwt/src/helpers/base64.js deleted file mode 100644 index bee601634894c24dabce1d953f5de2611dfee356..0000000000000000000000000000000000000000 --- a/packages/jwt/src/helpers/base64.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * encode input into base64 - * @param {*} in input - * @return {string} base64 output - */ -const base64Encode = in => Buffer.from(in).toString(BASE64_FORMAT) - -/** - * Decode base64 encoded string - * @param {string} in base64 encoded string - * @return {*} decoded payload - */ -const base64Decode = in => Buffer.from(in, BASE64_FORMAT) - -module.exports = { - base64Encode, - base64Decode -} diff --git a/packages/jwt/src/helpers/buff.js b/packages/jwt/src/helpers/buff.js deleted file mode 100644 index b711015bc645057da049f7c72341d63a22e24155..0000000000000000000000000000000000000000 --- a/packages/jwt/src/helpers/buff.js +++ /dev/null @@ -1,14 +0,0 @@ - -const { BASE64_FORMAT } = require('jsonql-constants'); -/** - * create a buffer from string - * @param {string} str to transform - * @param {string} [format=BASE64_FORMAT] format to use - * @return {buffer} tramsformed - */ -module.exports = function buff(str, format = BASE64_FORMAT) { - if (Buffer.isBuffer(str)) { - return str; - } - return new Buffer.from(str, format) -} diff --git a/packages/jwt/src/helpers/client-utils.js b/packages/jwt/src/helpers/client-utils.js deleted file mode 100644 index 6b16b2c804f1234c0ac4099bdbf6e668d9601288..0000000000000000000000000000000000000000 --- a/packages/jwt/src/helpers/client-utils.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var jsonqlParamsValidator = require('jsonql-params-validator'); - -// This is ported back from ws-server and it will get use in the server / client side - -function extractSocketPart(contract) { - if (jsonqlParamsValidator.isKeyInObject(contract, 'socket')) { - return contract.socket; - } - return contract; -} - -/** - * @BUG we should check the socket part instead of expect the downstream to read the menu! - * We only need this when the enableAuth is true otherwise there is only one namespace - * @param {object} contract the socket part of the contract file - * @return {object} 1. remap the contract using the namespace --> resolvers - * 2. the size of the object (1 all private, 2 mixed public with private) - * 3. which namespace is public - */ -function groupByNamespace(contract) { - var socket = extractSocketPart(contract); - - var nspSet = {}; - var size = 0; - var publicNamespace; - for (var resolverName in socket) { - var params = socket[resolverName]; - var namespace = params.namespace; - if (namespace) { - if (!nspSet[namespace]) { - ++size; - nspSet[namespace] = {}; - } - nspSet[namespace][resolverName] = params; - if (!publicNamespace) { - if (params.public) { - publicNamespace = namespace; - } - } - } - } - return { size: size, nspSet: nspSet, publicNamespace: publicNamespace } -} - -// This is ported back from ws-client -// the idea if from https://decembersoft.com/posts/promises-in-serial-with-array-reduce/ -/** - * previously we already make sure the order of the namespaces - * and attach the auth client to it - * @param {array} promises array of unresolved promises - * @return {object} promise resolved with the array of promises resolved results - */ -function chainPromises(promises) { - return promises.reduce(function (promiseChain, currentTask) { return ( - promiseChain.then(function (chainResults) { return ( - currentTask.then(function (currentResult) { return ( - chainResults.concat( [currentResult]) - ); }) - ); }) - ); }, Promise.resolve([])) -} - -exports.chainPromises = chainPromises; -exports.groupByNamespace = groupByNamespace; diff --git a/packages/jwt/src/helpers/index.js b/packages/jwt/src/helpers/index.js deleted file mode 100644 index 3987cb82aa2ea1b855710660d3262893acaf1862..0000000000000000000000000000000000000000 --- a/packages/jwt/src/helpers/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const buff = require('buff') - -module.exports = { - buff -} diff --git a/packages/jwt/src/jwt/decode-token.js b/packages/jwt/src/jwt/decode-token.js index e74222684212c9f9c851554a2577fb879367929f..3e5c4cead2b167b9fbd670f36dc7ad2242225eb3 100644 --- a/packages/jwt/src/jwt/decode-token.js +++ b/packages/jwt/src/jwt/decode-token.js @@ -7,16 +7,2016 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau var jwt_decode = _interopDefault(require('jwt-decode')); var jsonqlParamsValidator = require('jsonql-params-validator'); var jsonqlErrors = require('jsonql-errors'); +require('debug'); -// when the user is login with the jwt +var OPTIONAL_KEY = 'optional'; +var ALIAS_KEY = 'alias'; + +var STRING_TYPE = 'string'; +var BOOLEAN_TYPE = 'boolean'; + +var NUMBER_TYPE = 'number'; +var HSA_ALGO = 'HS256'; + +// bunch of generic helpers + +/** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ +var timestamp = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; +}; + +var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + +var lookup = []; +var revLookup = []; +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; +var inited = false; +function init () { + inited = true; + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + + revLookup['-'.charCodeAt(0)] = 62; + revLookup['_'.charCodeAt(0)] = 63; +} + +function toByteArray (b64) { + if (!inited) { + init(); + } + var i, j, l, tmp, placeHolders, arr; + var len = b64.length; + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len; + + var L = 0; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; + arr[L++] = (tmp >> 16) & 0xFF; + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); + arr[L++] = tmp & 0xFF; + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp; + var output = []; + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output.push(tripletToBase64(tmp)); + } + return output.join('') +} + +function fromByteArray (uint8) { + if (!inited) { + init(); + } + var tmp; + var len = uint8.length; + var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes + var output = ''; + var parts = []; + var maxChunkLength = 16383; // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1]; + output += lookup[tmp >> 2]; + output += lookup[(tmp << 4) & 0x3F]; + output += '=='; + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); + output += lookup[tmp >> 10]; + output += lookup[(tmp >> 4) & 0x3F]; + output += lookup[(tmp << 2) & 0x3F]; + output += '='; + } + + parts.push(output); + + return parts.join('') +} + +function read (buffer, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? (nBytes - 1) : 0; + var d = isLE ? -1 : 1; + var s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +function write (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); + var i = isLE ? 0 : (nBytes - 1); + var d = isLE ? 1 : -1; + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; +} + +var toString = {}.toString; + +var isArray = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +var INSPECT_MAX_BYTES = 50; + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length); + } + that.length = length; + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192; // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype; + return arr +}; + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +}; + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype; + Buffer.__proto__ = Uint8Array; +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size); + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +}; + +function allocUnsafe (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0; + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +}; +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +}; + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0; + that = createBuffer(that, length); + + var actual = that.write(string, encoding); + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual); + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0; + that = createBuffer(that, length); + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255; + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength; // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array); + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset); + } else { + array = new Uint8Array(array, byteOffset, length); + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array); + } + return that +} + +function fromObject (that, obj) { + if (internalIsBuffer(obj)) { + var len = checked(obj.length) | 0; + that = createBuffer(that, len); + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len); + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} +Buffer.isBuffer = isBuffer; +function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!internalIsBuffer(a) || !internalIsBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) { return 0 } + + var x = a.length; + var y = b.length; + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break + } + } + + if (x < y) { return -1 } + if (y < x) { return 1 } + return 0 +}; + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +}; + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer.allocUnsafe(length); + var pos = 0; + for (i = 0; i < list.length; ++i) { + var buf = list[i]; + if (!internalIsBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer +}; + +function byteLength (string, encoding) { + if (internalIsBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string; + } + + var len = string.length; + if (len === 0) { return 0 } + + // Use a for loop to avoid recursion + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) { return utf8ToBytes(string).length } // assume utf8 + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +} +Buffer.byteLength = byteLength; + +function slowToString (encoding, start, end) { + var loweredCase = false; + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0; + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length; + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0; + start >>>= 0; + + if (end <= start) { + return '' + } + + if (!encoding) { encoding = 'utf8'; } + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } + encoding = (encoding + '').toLowerCase(); + loweredCase = true; + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true; + +function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length; + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1); + } + return this +}; + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length; + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this +}; + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length; + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this +}; + +Buffer.prototype.toString = function toString () { + var length = this.length | 0; + if (length === 0) { return '' } + if (arguments.length === 0) { return utf8Slice(this, 0, length) } + return slowToString.apply(this, arguments) +}; + +Buffer.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } + if (this === b) { return true } + return Buffer.compare(this, b) === 0 +}; + +Buffer.prototype.inspect = function inspect () { + var str = ''; + var max = INSPECT_MAX_BYTES; + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' '); + if (this.length > max) { str += ' ... '; } + } + return '' +}; + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!internalIsBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0; + } + if (end === undefined) { + end = target ? target.length : 0; + } + if (thisStart === undefined) { + thisStart = 0; + } + if (thisEnd === undefined) { + thisEnd = this.length; + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0; + end >>>= 0; + thisStart >>>= 0; + thisEnd >>>= 0; + + if (this === target) { return 0 } + + var x = thisEnd - thisStart; + var y = end - start; + var len = Math.min(x, y); + + var thisCopy = this.slice(thisStart, thisEnd); + var targetCopy = target.slice(start, end); + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i]; + y = targetCopy[i]; + break + } + } + + if (x < y) { return -1 } + if (y < x) { return 1 } + return 0 +}; + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) { return -1 } + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = 0; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + byteOffset = +byteOffset; // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1); + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) { byteOffset = buffer.length + byteOffset; } + if (byteOffset >= buffer.length) { + if (dir) { return -1 } + else { byteOffset = buffer.length - 1; } + } else if (byteOffset < 0) { + if (dir) { byteOffset = 0; } + else { return -1 } + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding); + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (internalIsBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF; // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1; + var arrLength = arr.length; + var valLength = val.length; + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase(); + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2; + arrLength /= 2; + valLength /= 2; + byteOffset /= 2; + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i; + if (dir) { + var foundIndex = -1; + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) { foundIndex = i; } + if (i - foundIndex + 1 === valLength) { return foundIndex * indexSize } + } else { + if (foundIndex !== -1) { i -= i - foundIndex; } + foundIndex = -1; + } + } + } else { + if (byteOffset + valLength > arrLength) { byteOffset = arrLength - valLength; } + for (i = byteOffset; i >= 0; i--) { + var found = true; + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false; + break + } + } + if (found) { return i } + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +}; + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +}; + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +}; + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0; + var remaining = buf.length - offset; + if (!length) { + length = remaining; + } else { + length = Number(length); + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2 !== 0) { throw new TypeError('Invalid hex string') } + + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(parsed)) { return i } + buf[offset + i] = parsed; + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8'; + length = this.length; + offset = 0; + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0; + if (isFinite(length)) { + length = length | 0; + if (encoding === undefined) { encoding = 'utf8'; } + } else { + encoding = length; + length = undefined; + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset; + if (length === undefined || length > remaining) { length = remaining; } + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) { encoding = 'utf8'; } + + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) { throw new TypeError('Unknown encoding: ' + encoding) } + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } +}; + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +}; + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return fromByteArray(buf) + } else { + return fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end); + var res = []; + + var i = start; + while (i < end) { + var firstByte = buf[i]; + var codePoint = null; + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1; + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint; + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte; + } + break + case 2: + secondByte = buf[i + 1]; + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint; + } + } + break + case 3: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint; + } + } + break + case 4: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + fourthByte = buf[i + 3]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint; + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD; + bytesPerSequence = 1; + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000; + res.push(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + res.push(codePoint); + i += bytesPerSequence; + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000; + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length; + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = ''; + var i = 0; + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ); + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F); + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]); + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length; + + if (!start || start < 0) { start = 0; } + if (!end || end < 0 || end > len) { end = len; } + + var out = ''; + for (var i = start; i < end; ++i) { + out += toHex(buf[i]); + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end); + var res = ''; + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length; + start = ~~start; + end = end === undefined ? len : ~~end; + + if (start < 0) { + start += len; + if (start < 0) { start = 0; } + } else if (start > len) { + start = len; + } + + if (end < 0) { + end += len; + if (end < 0) { end = 0; } + } else if (end > len) { + end = len; + } + + if (end < start) { end = start; } + + var newBuf; + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer(sliceLen, undefined); + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start]; + } + } + + return newBuf +}; + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) { throw new RangeError('offset is not uint') } + if (offset + ext > length) { throw new RangeError('Trying to access beyond buffer length') } +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + + return val +}; + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + checkOffset(offset, byteLength, this.length); + } + + var val = this[offset + --byteLength]; + var mul = 1; + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul; + } + + return val +}; + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + return this[offset] +}; + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return this[offset] | (this[offset + 1] << 8) +}; + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return (this[offset] << 8) | this[offset + 1] +}; + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +}; + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +}; + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + mul *= 0x80; + + if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } + + return val +}; + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { checkOffset(offset, byteLength, this.length); } + + var i = byteLength; + var mul = 1; + var val = this[offset + --i]; + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul; + } + mul *= 0x80; + + if (val >= mul) { val -= Math.pow(2, 8 * byteLength); } + + return val +}; + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + if (!(this[offset] & 0x80)) { return (this[offset]) } + return ((0xff - this[offset] + 1) * -1) +}; + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + var val = this[offset] | (this[offset + 1] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + var val = this[offset + 1] | (this[offset] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val +}; + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +}; + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +}; + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, true, 23, 4) +}; + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, false, 23, 4) +}; + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, true, 52, 8) +}; + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, false, 52, 8) +}; + +function checkInt (buf, value, offset, ext, max, min) { + if (!internalIsBuffer(buf)) { throw new TypeError('"buffer" argument must be a Buffer instance') } + if (value > max || value < min) { throw new RangeError('"value" argument is out of bounds') } + if (offset + ext > buf.length) { throw new RangeError('Index out of range') } +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var mul = 1; + var i = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var i = byteLength - 1; + var mul = 1; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } + if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + this[offset] = (value & 0xff); + return offset + 1 +}; + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) { value = 0xffff + value + 1; } + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8; + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) { value = 0xffffffff + value + 1; } + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff; + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24); + this[offset + 2] = (value >>> 16); + this[offset + 1] = (value >>> 8); + this[offset] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = 0; + var mul = 1; + var sub = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = byteLength - 1; + var mul = 1; + var sub = 0; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength +}; + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } + if (!Buffer.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + if (value < 0) { value = 0xff + value + 1; } + this[offset] = (value & 0xff); + return offset + 1 +}; + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 +}; + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 +}; + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + this[offset + 2] = (value >>> 16); + this[offset + 3] = (value >>> 24); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 +}; + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (value < 0) { value = 0xffffffff + value + 1; } + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 +}; + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) { throw new RangeError('Index out of range') } + if (offset < 0) { throw new RangeError('Index out of range') } +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4); + } + write(buf, value, offset, littleEndian, 23, 4); + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +}; + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8); + } + write(buf, value, offset, littleEndian, 52, 8); + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +}; + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +}; + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) { start = 0; } + if (!end && end !== 0) { end = this.length; } + if (targetStart >= target.length) { targetStart = target.length; } + if (!targetStart) { targetStart = 0; } + if (end > 0 && end < start) { end = start; } + + // Copy 0 bytes; we're done + if (end === start) { return 0 } + if (target.length === 0 || this.length === 0) { return 0 } + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) { throw new RangeError('sourceStart out of bounds') } + if (end < 0) { throw new RangeError('sourceEnd out of bounds') } + + // Are we oob? + if (end > this.length) { end = this.length; } + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start; + } + + var len = end - start; + var i; + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start]; + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start]; + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ); + } + + return len +}; + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start; + start = 0; + end = this.length; + } else if (typeof end === 'string') { + encoding = end; + end = this.length; + } + if (val.length === 1) { + var code = val.charCodeAt(0); + if (code < 256) { + val = code; + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255; + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0; + end = end === undefined ? this.length : end >>> 0; + + if (!val) { val = 0; } + var i; + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val; + } + } else { + var bytes = internalIsBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()); + var len = bytes.length; + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len]; + } + } + + return this +}; + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g; + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, ''); + // Node converts strings with length < 2 to '' + if (str.length < 2) { return '' } + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '='; + } + return str +} + +function stringtrim (str) { + if (str.trim) { return str.trim() } + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) { return '0' + n.toString(16) } + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity; + var codePoint; + var length = string.length; + var leadSurrogate = null; + var bytes = []; + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + continue + } + + // valid lead + leadSurrogate = codePoint; + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + leadSurrogate = codePoint; + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) { bytes.push(0xEF, 0xBF, 0xBD); } + } + + leadSurrogate = null; + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) { break } + bytes.push(codePoint); + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) { break } + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) { break } + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) { break } + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF); + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo; + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) { break } + + c = str.charCodeAt(i); + hi = c >> 8; + lo = c % 256; + byteArray.push(lo); + byteArray.push(hi); + } + + return byteArray +} + + +function base64ToBytes (str) { + return toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) { break } + dst[i + offset] = src[i]; + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + + +// the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +function isBuffer(obj) { + return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) +} + +function isFastBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) +} + +if (typeof global$1.setTimeout === 'function') ; +if (typeof global$1.clearTimeout === 'function') ; + +// from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js +var performance = global$1.performance || {}; +var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + +// when the user is login with the jwt /** * We only check the nbf and exp * @param {object} token for checking * @return {object} token on success */ function validate(token) { - var start = token.iat || Math.floor(Date.now() / 1000); + var start = token.iat || timestamp(); // we only check the exp for the time being if (token.exp) { if (start >= token.exp) { @@ -42,15 +2042,6 @@ function jwtDecode(token) { throw new jsonqlErrors.JsonqlError('Token must be a string!') } -var OPTIONAL_KEY = 'optional'; -var ALIAS_KEY = 'alias'; - -var STRING_TYPE = 'string'; -var BOOLEAN_TYPE = 'boolean'; - -var NUMBER_TYPE = 'number'; -var HSA_ALGO = 'HS256'; - var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; var appProps = { diff --git a/packages/jwt/src/jwt/jwt-decode.js b/packages/jwt/src/jwt/jwt-decode.js index 32e5c94c0471aaf52228214b24a2ba6b48585025..16f51d4134167e73cf08488ce74253ed2748daca 100644 --- a/packages/jwt/src/jwt/jwt-decode.js +++ b/packages/jwt/src/jwt/jwt-decode.js @@ -2,11 +2,9 @@ const jwt = require('jsonwebtoken') const { RSA_ALGO } = require('jsonql-constants') const { isString } = require('jsonql-params-validator') const { JsonqlError } = require('jsonql-errors') -const buff = require('../helpers/buff') - -const baseOptions = { - algorithms: RSA_ALGO -}; +const { buff } = require('jsonql-utils') +// variable +const baseOptions = { algorithms: RSA_ALGO } /** * @param {string} token to decrypted * @param {string} key public key diff --git a/packages/jwt/src/jwt/jwt-token.js b/packages/jwt/src/jwt/jwt-token.js index b83e41a9931d963e4a32ed4b40b75e678e5e8fe9..3717248288b777a386e6ac3f90f98211212ca483 100644 --- a/packages/jwt/src/jwt/jwt-token.js +++ b/packages/jwt/src/jwt/jwt-token.js @@ -1,8 +1,11 @@ const jwt = require('jsonwebtoken') -const { HSA_ALGO, RSA_ALGO } = require('jsonql-constants') -const buff = require('../helpers/buff') +const { HSA_ALGO, RSA_ALGO, BASE64_FORMAT } = require('jsonql-constants') +const { buff } = require('jsonql-utils') + const { tokenValidator } = require('./decode-token') -const debug = require('debug')('jsonql-jwt:jwt-token') + +const baseOptions = { algorithm: HSA_ALGO } + /* NOTES about the options: @@ -18,9 +21,7 @@ header keyid mutatePayload */ -const baseOptions = { - algorithm: HSA_ALGO -}; + /** * Generate a jwt token * @param {object} payload object @@ -30,9 +31,8 @@ const baseOptions = { */ module.exports = function jwtToken(payload, secret, options = {}) { if (options.algorithm === RSA_ALGO) { - secret = buff(secret); + secret = buff(secret) } const opts = tokenValidator(options) - debug(opts) return jwt.sign(payload, secret, opts) } diff --git a/packages/jwt/src/server/auth/create-token-validator.js b/packages/jwt/src/server/auth/create-token-validator.js index e411760b7bb03ea8db7c2794477ac3ca2fd51847..7f906e4fbaf911ffe3cffb5b2032b802faeaca95 100644 --- a/packages/jwt/src/server/auth/create-token-validator.js +++ b/packages/jwt/src/server/auth/create-token-validator.js @@ -3,7 +3,7 @@ const { JsonqlValidatorError } = require('jsonql-errors') const { isString } = require('jsonql-params-validator') const { RSA_ALGO, HSA_ALGO } = require('jsonql-constants') const jwtDecode = require('../../jwt/jwt-decode') -const debug = require('debug')('jsonql-jwt:create-token-valdiator') + /** * This will overwrite the developer provide one when useJwt is enable * @param {object} config configuration from the jsonql-koa @@ -25,7 +25,6 @@ module.exports = function createTokenValidator(config) { throw new JsonqlValidatorError(`key is not provided!`) } return function tokenValidator(token) { - debug('received token for validatiion', token) return jwtDecode(token, key, opts) } } diff --git a/packages/jwt/src/server/auth/provide-userdata.js b/packages/jwt/src/server/auth/provide-userdata.js index 28ba4a464ba793fa426b9f44fbd3bccf4fc271b4..981f69ecdacd9a400e0345847a2172b3d500dd6c 100644 --- a/packages/jwt/src/server/auth/provide-userdata.js +++ b/packages/jwt/src/server/auth/provide-userdata.js @@ -1,3 +1,4 @@ +const { injectToFn } = require('jsonql-utils') /** * After the user login we will use this Object.define add a new property * to the resolver with the decoded user data @@ -6,9 +7,5 @@ * @return {function} added property resolver */ module.exports = function(resolver, userdata) { - Object.defineProperty(resolver, 'userdata', { - value: userdata, - writable: false // make this immutatble - }) - return resolver; + return injectToFn(resolver, 'userdata', userdata, true) } diff --git a/packages/jwt/src/server/index.js b/packages/jwt/src/server/index.js index 945fd80ed1aa3d023f0f4ce9a37c74d38dff9166..9a2802a2bd20187a8ef61d7d7464cef6c6d5704a 100644 --- a/packages/jwt/src/server/index.js +++ b/packages/jwt/src/server/index.js @@ -1,24 +1,12 @@ +/* moved to @jsonql/socketio const socketIoJwtAuth = require('./socketio/socketio-jwt-auth') const socketIoHandshakeAuth = require('./socketio/handshake-auth') const socketIoGetUserdata = require('./socketio/get-userdata') -/* -@NOTE all of these methods move back to ws-client since v1.2.5 -const { - socketIoNodeHandshakeLogin, - socketIoNodeRoundtripLogin, - - socketIoNodeClient, - socketIoNodeClientAsync, - - socketIoChainHSConnect, - socketIoChainRTConnect -} = require('./socketio/node-clients') -const { wsNodeClient, wsNodeAuthClient } = require('./ws/ws-client') */ -// ws +/* moved to @jsonql/ws const wsVerifyClient = require('./ws/verify-client') - const wsGetUserdata = require('./ws/get-userdata') +*/ // auth const loginResultToJwt = require('./auth/login-result-to-jwt') const provideUserdata = require('./auth/provide-userdata') @@ -26,15 +14,6 @@ const createTokenValidator = require('./auth/create-token-validator') module.exports = { - - socketIoGetUserdata, - socketIoJwtAuth, - socketIoHandshakeAuth, - - wsVerifyClient, - - wsGetUserdata, - loginResultToJwt, provideUserdata, createTokenValidator diff --git a/packages/jwt/src/server/socketio/clients.js b/packages/jwt/src/server/socketio/clients.js deleted file mode 100644 index c61013f34a33cb276a3c8da1a08c710d54113f31..0000000000000000000000000000000000000000 --- a/packages/jwt/src/server/socketio/clients.js +++ /dev/null @@ -1,159 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var jsonqlErrors = require('jsonql-errors'); -require('jsonql-params-validator'); - -// this should work on browser as well as node -// import io from 'socket.io-cilent' - -/** - * Create a normal client - * @param {object} io socket io instance - * @param {string} url end point - * @param {object} [options={}] configuration - * @return {object} nsp instance - */ -function socketIoClient(io, url, options) { - if ( options === void 0 ) options = {}; - - return io.connect(url, options) -} - -// this is the default time to wait for reply if exceed this then we -// trigger an error --> 5 seconds -var DEFAULT_WS_WAIT_TIME = 5000; -var TOKEN_PARAM_NAME = 'token'; -var IO_ROUNDTRIP_LOGIN = 'roundtip'; -var IO_HANDSHAKE_LOGIN = 'handshake'; - -// handshake login - -/** - * Create a async version to match up the rest of the api - * @param {object} io socket io instance - * @param {string} url end point - * @param {object} [options={}] configuration - * @return {object} Promise resolve to nsp instance - */ -function socketIoClientAsync() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - return Promise.resolve( - Reflect.apply(socketIoClient, null, args) - ) -} - -/** - * Login during handshake - * @param {object} io the new socket.io instance - * @param {string} token to send - * @param {object} [options = {}] extra options - * @return {object} the io object itself - */ -function socketIoHandshakeLogin(io, url, token, options) { - if ( options === void 0 ) options = {}; - - var wait = options.timeout || DEFAULT_WS_WAIT_TIME; - var config = Object.assign({}, options, { - query: [TOKEN_PARAM_NAME, token].join('=') - }); - var timer; - var nsp = socketIoClient(io, url, config); - return new Promise(function (resolver, rejecter) { - timer = setTimeout(function () { - rejecter(); - }, wait); - nsp.on('connect', function () { - console.info('socketIoHandshakeLogin connected'); - resolver(nsp); - clearTimeout(timer); - }); - }) -} - -// import { isString } from 'jsonql-params-validator'; -/** - * The core method of the socketJwt client side - * @param {object} socket the socket.io connected instance - * @param {string} token for validation - * @param {function} onAuthenitcated callback when authenticated - * @param {function} onUnauthorized callback when authorized - * @return {void} - */ -var socketIoLoginAction = function (socket, token, onAuthenticated, onUnauthorized) { - socket - .emit('authenticate', { token: token }) - .on('authenticated', onAuthenticated) - .on('unauthorized', onUnauthorized); -}; - -/** - * completely rethink about how the browser version should be! - * - */ -function socketIoRoundtripLogin(io, url, token, options) { - - var socket = socketIoClient(io, url); - return new Promise(function (resolver, rejecter) { - socketIoLoginAction(socket, token, function () { return resolver(socket); } , rejecter); - }) -} - -// this will combine two namespaces and chain them together in a promises chain -/** - * Type of client - * @param {string} type for checking - * @return {function} or throw error - */ -function getAuthClient(type) { - console.info('client type: ', type); - switch (type) { - case IO_ROUNDTRIP_LOGIN: - return socketIoRoundtripLogin; - case IO_HANDSHAKE_LOGIN: - return socketIoHandshakeLogin; - default: - throw new jsonqlErrors.JsonqlValidationError('socketIoChainConnect', {message: ("Unknown " + type + " of client!")}) - } -} - -/** - * @param {object} io socket.io-client - * @param {string} baseUrl to connect - * @param {array} namespaces to append to baseUrl - * @param {string} token for validation - * @param {array} options passing to the clients - * @param {string} [ type = IO_HANDSHAKE_LOGIN ] of client to use - * @return {object} promise resolved n*nsps in order - */ -function socketIoChainConnect(io, baseUrl, namespaces, token, type, options) { - if ( type === void 0 ) type = IO_HANDSHAKE_LOGIN; - - // we expect the order is auth url first - return new Promise(function (resolver, rejecter) { - var authUrl = [baseUrl, namespaces[0]].join(''); - var fn1 = Reflect.apply(getAuthClient(type), null, [io, authUrl, token]); - fn1.then(function (nsp1) { - var publicUrl = [baseUrl, namespaces[1]].join(''); - var fn2 = Reflect.apply(socketIoClientAsync, null, [io, publicUrl]); - fn2.then(function (nsp2) { - resolver([nsp1, nsp2]); - }) - .catch(function (err2) { - rejecter({message: ("failed on " + publicUrl), error: err2}); - }); - }) - .catch(function (err1) { - rejecter({message: ("failed on " + authUrl), error: err1}); - }); - }) -} - -exports.socketIoChainConnect = socketIoChainConnect; -exports.socketIoClient = socketIoClient; -exports.socketIoClientAsync = socketIoClientAsync; -exports.socketIoHandshakeLogin = socketIoHandshakeLogin; -exports.socketIoRoundtripLogin = socketIoRoundtripLogin; diff --git a/packages/resolver/package.json b/packages/resolver/package.json index b54ec98e297f087e46ce37617a65ea07b1e51f04..627488e3d16f43b2ceaf4f4217808c435e62a487 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-resolver", - "version": "0.6.5", + "version": "0.7.0", "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": [ @@ -17,19 +17,23 @@ ], "author": "Joel Chu ", "license": "ISC", + "homepage": "https://jsonql.js.org", + "bugs": { + "url": "https://gitee.com/to1source/jsonql/issues" + }, "dependencies": { - "debug": "^4.1.1", - "jsonql-constants": "^1.7.9", + "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-jwt": "^1.2.5", - "jsonql-node-client": "^1.1.5", + "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", + "jsonql-utils": "^0.3.8", "lodash.merge": "^4.6.2" }, "devDependencies": { "ava": "^2.3.0", "jsonql-contract": "^1.7.7", - "jsonql-koa": "^1.3.7", + "jsonql-koa": "^1.3.8", "server-io-core": "^1.2.0" }, "ava": { diff --git a/packages/resolver/src/client/validate-client-config.js b/packages/resolver/src/client/validate-client-config.js index bed7e877e953f8579d720f91e21183849341f7ed..d96067ec8e21292c508420f30befe4fc037fef6c 100644 --- a/packages/resolver/src/client/validate-client-config.js +++ b/packages/resolver/src/client/validate-client-config.js @@ -1,5 +1,7 @@ const { join } = require('path') -const { getDebug, inArray } = require('../utils') +const { inArray } = require('jsonql-utils') +const { JsonqlError } = require('jsonql-errors') +const { getDebug } = require('../utils') const debug = getDebug('validate-client-config') /** * Double check if the client config is correct or not also we could inject some of the properties here @@ -16,14 +18,14 @@ const validateClientConfig = function(config) { for (let i = 0; i < ctn; ++i) { let client = config.clientConfig[i] if (!client.hostname) { - throw new Error(`Missing hostname in client config ${i}`) + throw new JsonqlError(`Missing hostname in client config ${i}`) } debug(`name: ${client.name}`) if (!client.name) { client.name = `nodeClient${i}` } if (inArray(names, client.name)) { - throw new Error(`[${i}] ${client.name} already existed, can not have duplicated!`) + throw new JsonqlError(`[${i}] ${client.name} already existed, can not have duplicated!`) } names.push(client.name) // next we need to create contract dir path using the name diff --git a/packages/resolver/src/handle-auth-methods.js b/packages/resolver/src/handle-auth-methods.js index 33e846e5cd2854e1fb9fc9cc825985da3cabef01..eeef537bea0bf0b0976893147c3bee178b5d1438 100644 --- a/packages/resolver/src/handle-auth-methods.js +++ b/packages/resolver/src/handle-auth-methods.js @@ -1,13 +1,8 @@ -const { - getDebug, - handleOutput, - packResult, - ctxErrorHandler -} = require('./utils') - +const { getDebug } = require('./utils') const searchResolvers = require('./search-resolvers') const validateAndCall = require('./validate-and-call') +const { handleOutput, packResult, ctxErrorHandler } = require('jsonql-utils') const { QUERY_NAME, MUTATION_NAME, diff --git a/packages/resolver/src/provide-node-clients.js b/packages/resolver/src/provide-node-clients.js index d35f96cd37a76bd865cf8f2ac89265dd300c2ed1..0faec158ac25208c456e380f5f10acb67622819a 100644 --- a/packages/resolver/src/provide-node-clients.js +++ b/packages/resolver/src/provide-node-clients.js @@ -4,9 +4,7 @@ const { validateClientConfig, clientsGenerator } = require('./client') -const { - getDebug -} = require('./utils') +const { getDebug } = require('./utils') const debug = getDebug('provide-node-clients') let clients = [] let hasClientConfig; diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index 381c8c7331b49813b6d4c987b5bb4d7111bf6360..e487d2cb5d9460886ee0578dca882280df385f6f 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -9,23 +9,19 @@ const { getErrorNameByInstance, UNKNOWN_ERROR } = require('jsonql-errors') +// @TODO this should move to the jsonql-utils! const { provideUserdata } = require('jsonql-jwt') const { MODULE_TYPE, - DEFAULT_RESOLVER_IMPORT_FILE_NAME, - QUERY_NAME, - MUTATION_NAME, - PAYLOAD_PARAM_NAME, - CONDITION_PARAM_NAME, - RESOLVER_PARAM_NAME , - QUERY_ARG_NAME + DEFAULT_RESOLVER_IMPORT_FILE_NAME } = require('jsonql-constants') const { - getDebug, handleOutput, ctxErrorHandler, - packResult -} = require('./utils') + packResult, + extractArgsFromPayload +} = require('jsonql-utils') +const { getDebug } = require('./utils') const searchResolvers = require('./search-resolvers') const validateAndCall = require('./validate-and-call') const provideNodeClients = require('./provide-node-clients') @@ -33,26 +29,7 @@ const provideNodeClients = require('./provide-node-clients') const debug = getDebug('resolve-method') /** - * Extract the args from the payload - * @param {object} payload to work with - * @param {string} type of call - * @return {array} args - */ -const extractArgsFromPayload = function(payload, type) { - switch (type) { - case QUERY_NAME: - return payload[QUERY_ARG_NAME]; - case MUTATION_NAME: - return [ - payload[PAYLOAD_PARAM_NAME], - payload[CONDITION_PARAM_NAME] - ]; - default: - throw new JsonqlError(`Unknown ${type} to extract argument from!`) - } -} - -/** + * @TODO we might have to change to the contract folder instead * New for ES6 module features * @param {string} resolverDir resolver directory * @param {string} type of resolver diff --git a/packages/resolver/src/search-resolvers.js b/packages/resolver/src/search-resolvers.js index 43cb2787ac20346f25d83684201a969a5a521573..67706a6b1a494b1d37e35942b3d60714b48f35c1 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -1,54 +1,14 @@ // search for the resolver location -const fs = require('fs') const { join } = require('path') const { JsonqlResolverNotFoundError } = require('jsonql-errors') +const { getPathToFn, findFromContract } = require('jsonql-utils') + const { getDebug } = require('./utils') const debug = getDebug('search-resolvers') const prod = process.env.NODE_ENV === 'production'; -/** - * @param {string} name - * @param {string} type - * @param {object} opts - * @return {function} - */ -const getPathToFn = function(name, type, opts) { - const dir = opts.resolverDir; - const fileName = dasherize(name); - let paths = []; - if (opts.contract && opts.contract[type] && opts.contract[type].path) { - paths.push(opts.contract[type].path) - } - paths.push( join(dir, type, fileName, 'index.js') ) - paths.push( join(dir, type, fileName + '.js') ) - - const ctn = paths.length; - for (let i=0; i ( - (str+'') - .trim() - .replace(/([A-Z])/g, '-$1') - .replace(/[-_\s]+/g, '-') - .toLowerCase() -) +const { getDebug } = require('jsonql-utils') -// export a create debug method -const debug = require('debug') -/** - * @param {string} name for id - * @param {boolean} cond i.e. NODE_ENV==='development' - * @return {void} nothing - */ -const getDebug = (name, cond = true) => ( - cond ? debug('jsonql-resolver').extend(name) : () => {} -) - -/** - * DIY in Array - * @param {array} arr to check from - * @param {*} value to check against - * @return {boolean} true on found - */ -const inArray = (arr, value) => !!arr.filter(a => a === value).length; - -/** - * Get document (string) byte length for use in header - * @param {string} doc to calculate - * @return {number} length - */ -const getDocLen = doc => Buffer.byteLength(doc, 'utf8') - -/** - * wrapper method - * @param {mixed} result of fn return - * @return {string} stringify data - */ -const packResult = result => { - return JSON.stringify({ data: result }) -} - -/** - * wrapper method - the output is trying to match up the structure of the Error sub class - * @param {mixed} detail of fn error - * @param {string} [className=JsonqlError] the errorName - * @param {number} [statusCode=500] the original error code - * @return {string} stringify error - */ -const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { - return JSON.stringify({ - error: { detail, className, statusCode, message } - }) -} - -/** - * Handle the output - * @param {object} opts configuration - * @return {function} with ctx and body as params - */ -const handleOutput = function(opts) { - return function(ctx, body) { - ctx.size = getDocLen(body) - ctx.type = opts.contentType; - ctx.status = 200; - ctx.body = body; - } -} - -/** - * use the ctx to generate error output - * V1.1.0 we render this as a normal output with status 200 - * then on the client side will check against the result object for error - * @param {object} ctx context - * @param {number} code 404 / 500 etc - * @param {object} e actual error - * @param {string} message if there is one - * @param {string} name custom error class name - */ -const ctxErrorHandler = function(ctx, code, e, message = '') { - const render = handleOutput({contentType: CONTENT_TYPE}) - let name; - if (typeof code === 'string') { - name = code; - code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1; - } else { - name = jsonqlErrors.getErrorByStatus(code) - } - // preserve the message - if (!message && e && e.message) { - message = e.message; - } - return render(ctx, packError(e, name, code, message)) -} - -/** - * @param {array} clients node clients - * @param {string} name of the client - * @return {object|false} the client, false when failed - */ -function findClient(clients, name) { - return clients - .filter(client => client.name === name) - .reduce((base, result) => { - return result || base; - }, false) -} - -// export module.exports = { - inArray, - getDebug, - getDocLen, - packResult, - ctxErrorHandler, - isObject, - handleOutput, - findClient + getDebug: function(name) { + return getDebug(name, 'jsonql-resolver') + } } diff --git a/packages/utils/README.md b/packages/utils/README.md index 44de9a659e104d802727212542a656cf65c1ba54..8a59c0956ca7116abbd91f8020194292ba54d69e 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -1,8 +1,47 @@ -# jsonql-util +# jsonql-utils -This is a dependency module for various jsonql node modules. +> This is a dependency module for various jsonql node / browser modules. Not intend to use directly -Please check [jsonql.org](http://jsonql.org) for more information. +Please check [jsonql](https://jsonql.js.org) for more information. + +## complete list of all available functions + +- chainFns +- chainPromises +- checkIsContract +- extractSocketPart +- groupByNamespace +- isContract +- replaceErrors +- printError +- getDebug +- inArray +- isKeyInObject +- isJsonqlPath +- isJsonqlRequest +- isJsonqlConsoleUrl +- dasherize +- getDocLen +- headerParser +- isHeaderPresent +- getCallMethod +- getPathToFn +- packResult +- packError +- createQuery +- createQueryStr +- createMutation +- createMutationStr +- getQueryFromArgs +- getQueryFromPayload +- getMutationFromArgs +- getMutationFromPayload +- getNameFromPayload +- _Koa Specific helpers_ + - handleOutput + - handleHtmlOutput + - ctxErrorHandler + - forbiddenHandler --- diff --git a/packages/utils/es.js b/packages/utils/es.js new file mode 100644 index 0000000000000000000000000000000000000000..efc4dba40fe6cf33d752a854b0609ab06253958f --- /dev/null +++ b/packages/utils/es.js @@ -0,0 +1,118 @@ +// exportfor ES modules +// ported from jsonql-params-validator +import { chainFns, chainPromises } from './src/chain-fns' +import { + checkIsContract, + extractSocketPart, + groupByNamespace, + findFromContract, + extractArgsFromPayload, + extractParamsFromContract +} from './src/contract' +import { replaceErrors, printError } from './src/error' +import { + getDebug, + inArray, + toArray, + isKeyInObject, + injectToFn, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, + dasherize +} from './src/generic' +import { + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler +} from './src/koa' +import { + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError, + resultHandler +} from './src/middleware' +import { + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload +} from './src/params-api' +import { buff } from './src/jwt' +import { objDefineProps } from './src/obj-define-props' +// alias +const isContract = checkIsContract; +// exports +export { + // chain-fns + chainFns, + chainPromises, + // contract + findFromContract, + extractArgsFromPayload, + extractParamsFromContract, + checkIsContract, + extractSocketPart, + groupByNamespace, + isContract, // alias + // error + replaceErrors, + printError, + // generic + getDebug, + inArray, + isKeyInObject, + injectToFn, + dasherize, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, + // koa + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler, + // middleware + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError, + resultHandler, + // params-api + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload, + // node + buff, + // objectDefineProp + objDefineProps +} diff --git a/packages/utils/index.js b/packages/utils/index.js deleted file mode 100644 index 8e2ff9534c624699f1f4e86f4f40ee705fbf5db4..0000000000000000000000000000000000000000 --- a/packages/utils/index.js +++ /dev/null @@ -1,12 +0,0 @@ -// exportfor ES modules -// ported from jsonql-params-validator - -import { chainFns, chainPromises } from './src/chain-fns' - - -// exports -export { - // chain-fns - chainFns, - chainPromises -} diff --git a/packages/utils/main.js b/packages/utils/main.js index 188245a229d0ee6d6c685eaed77232af23df0cc9..17d9c0d6dca64aff2e79cb6a7931a94c8d7ba6bd 100644 --- a/packages/utils/main.js +++ b/packages/utils/main.js @@ -1,3 +1,3 @@ // export for CJS modules using esm modules require = require('esm')(module) -module.exports = require('./index.js') +module.exports = require('./es.js') diff --git a/packages/utils/package.json b/packages/utils/package.json index 81c989e4f52dd079adf92abacbc531605fa723b4..13ea4b344d0d7353ad5792ce59a007f2e0e8a567 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,11 +1,17 @@ { "name": "jsonql-utils", - "version": "1.0.0", - "description": "This is not for generate use, it's for jsonql various modules", + "version": "0.4.1", + "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", - "module": "index.js", + "module": "es.js", + "files": [ + "main.js", + "es.js", + "src" + ], "scripts": { - "test": "ava", + "test": "ava --verbose", + "prepare": "npm run test", "test:params": "DEBUG=jsonql* ava ./tests/params-api.test.js" }, "keywords": [ @@ -14,10 +20,17 @@ ], "author": "Joel Chu ", "license": "ISC", + "engine": { + "node": ">=8" + }, "repository": { "type": "git", "url": "git+ssh://git@gitee.com:to1source/jsonql.git" }, + "homepage": "https://jsonql.js.org", + "bugs": { + "url": "https://gitee.com/to1source/jsonql/issues" + }, "ava": { "files": [ "tests/*.test.js", @@ -38,11 +51,12 @@ "dependencies": { "debug": "^4.1.1", "esm": "^3.2.25", - "jsonql-constants": "^1.7.9", + "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "lodash-es": "^4.17.15" }, "devDependencies": { - "ava": "^2.3.0" + "ava": "^2.3.0", + "fs-extra": "^8.1.0" } } diff --git a/packages/utils/src/chain-fns.js b/packages/utils/src/chain-fns.js index d9ad6c9b384fb7774899ce5a76f2a3e4d011aa57..08b8209366ac158abc5bcb5b6a23db7cc7a51e35 100644 --- a/packages/utils/src/chain-fns.js +++ b/packages/utils/src/chain-fns.js @@ -16,7 +16,6 @@ export const chainFns = (mainFn, ...moreFns) => ( ) ) - /** * previously we already make sure the order of the namespaces * and attach the auth client to it diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index da99ce35cda43f38d6e6eb716ca9f1cd47c11fb4..593139a6f1dd0788cbba644122f65fa73bde5acc 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -1,6 +1,31 @@ // contract related methods // This is ported back from ws-server and it will get use in the server / client side +import fs from 'fs' +import { + QUERY_NAME, + MUTATION_NAME, + SOCKET_NAME, + QUERY_ARG_NAME, + PAYLOAD_PARAM_NAME, + CONDITION_PARAM_NAME +} from 'jsonql-constants' +import { JsonqlError, JsonqlResolverNotFoundError } from 'jsonql-errors' import { isKeyInObject } from './generic' +import { isPlainObject } from 'lodash-es' + +/** + * Check if the json is a contract file or not + * @param {object} contract json object + * @return {boolean} true + */ +export function checkIsContract(contract) { + return isPlainObject(contract) + && ( + isKeyInObject(contract, QUERY_NAME) + || isKeyInObject(contract, MUTATION_NAME) + || isKeyInObject(contract, SOCKET_NAME) + ) +} /** * Ported from jsonql-params-validator but different @@ -8,7 +33,7 @@ import { isKeyInObject } from './generic' * @param {object} contract the contract object * @return {object|boolean} false on failed */ -function extractSocketPart(contract) { +export function extractSocketPart(contract) { if (isKeyInObject(contract, 'socket')) { return contract.socket; } @@ -19,14 +44,18 @@ function extractSocketPart(contract) { * @BUG we should check the socket part instead of expect the downstream to read the menu! * We only need this when the enableAuth is true otherwise there is only one namespace * @param {object} contract the socket part of the contract file + * @param {boolean} [fallback=false] this is a fall back option for old code * @return {object} 1. remap the contract using the namespace --> resolvers * 2. the size of the object (1 all private, 2 mixed public with private) * 3. which namespace is public */ -export default function groupByNamespace(contract) { +export function groupByNamespace(contract, fallback = false) { let socket = extractSocketPart(contract) if (socket === false) { - throw new Error(`socket not found in contract!`) + if (fallback) { + return contract; // just return the whole contract + } + throw new JsonqlError(`socket not found in contract!`) } let nspSet = {}; let size = 0; @@ -49,3 +78,61 @@ export default function groupByNamespace(contract) { } return { size, nspSet, publicNamespace } } + +/** + * ported from jsonql-resolver + * Using the contract to find the function to call + * @param {string} type of resolver + * @param {string} name of resolver + * @param {object} contract to search from + * @return {string} file path to function + */ +export function findFromContract(type, name, contract) { + if (contract[type] && contract[type][name] && contract[type][name].file) { + if (fs.existsSync(contract[type][name].file)) { + return contract[type][name].file; + } + } + return false; +} + +/** + * Extract the args from the payload + * @param {object} payload to work with + * @param {string} type of call + * @return {array} args + */ +export function extractArgsFromPayload(payload, type) { + switch (type) { + case QUERY_NAME: + return payload[QUERY_ARG_NAME]; + case MUTATION_NAME: + return [ + payload[PAYLOAD_PARAM_NAME], + payload[CONDITION_PARAM_NAME] + ]; + default: + throw new JsonqlError(`Unknown ${type} to extract argument from!`) + } +} + +/** + * Like what the name said + * @param {object} contract the contract json + * @param {string} type query|mutation + * @param {string} name of the function + * @return {object} the params part of the contract + */ +export function extractParamsFromContract(contract, type, name) { + try { + const result = contract[type][name]; + // debug('extractParamsFromContract', result) + if (!result) { + // debug(name, type, contract) + throw new JsonqlResolverNotFoundError(name, type) + } + return result; + } catch(e) { + throw new JsonqlResolverNotFoundError(name, e) + } +} diff --git a/packages/utils/src/error.js b/packages/utils/src/error.js index 64e894e8ec179eb5a6947337bcefde0f36e3afa3..9679b340ce21e1f5b0fa4e8b1481051e51bd5892 100644 --- a/packages/utils/src/error.js +++ b/packages/utils/src/error.js @@ -1,12 +1,12 @@ // some useful methods for error handling -const { inspect } = require('util') +import { inspect } from 'util' /** * Port this from the CIS App * @param {string} key of object * @param {mixed} value of object * @return {string} of things we after */ -const replaceErrors = function(key, value) { +export const replaceErrors = function(key, value) { if (value instanceof Error) { var error = {}; Object.getOwnPropertyNames(value).forEach(function (key) { @@ -22,14 +22,8 @@ const replaceErrors = function(key, value) { * @param {object} error obj * @return {string} printable result */ -const printError = function(error) { +export const printError = function(error) { //return 'MASKED'; //error.toString(); // return JSON.stringify(error, replaceErrors); return inspect(error, false, null, true) } - - -module.exports = { - replaceErrors, - printError -} diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index bec690efda61f1ba3d4bb69bfe8400c65a5ef1b6..0201c98f0613da84932a3f53890ab3c40cffac26 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -1,14 +1,13 @@ // bunch of generic helpers import debug from 'debug' -// import * as _ from 'lodash-es' - +import { isArray } from 'lodash-es' /** * @param {string} name the name part after the : * @param {string} baseName the base before the : */ export const getDebug = (name, baseName = 'jsonql') => { - debug(baseName).extend(name) + return debug(baseName).extend(name) } /** @@ -19,12 +18,96 @@ export const getDebug = (name, baseName = 'jsonql') => { */ 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]; + /** * @param {object} obj for search * @param {string} key target * @return {boolean} true on success */ -export const checkKeyInObject = function(obj, key) { +export const isKeyInObject = function(obj, key) { const keys = Object.keys(obj) return inArray(keys, key) } + +/** + * After the user login we will use this Object.define add a new property + * to the resolver with the decoded user data + * @param {function} resolver target resolver + * @param {string} name the name of the object to get inject also for checking + * @param {object} data to inject into the function static interface + * @param {boolean} [overwrite=false] if we want to overwrite the existing data + * @return {function} added property resolver + */ +export function injectToFn(resolver, name, data, overwrite = false) { + let check = Object.getOwnPropertyDescriptor(resolver, name) + if (ovewrite === false && check !== undefined) { + return resolver; + } + + Object.defineProperty(resolver, name, { + value: data, + writable: false // make this immutatble + }) + + return resolver; +} + +/** + * create a event name + * @param {string[]} args + * @return {string} event name for use + */ +export const createEvt = (...args) => args.join('_') + +/** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ +export const timestamp = (sec = false) => { + let time = Date.now() + return sec ? Math.floor( time / 1000 ) : time; +} + +/** + * construct a url with query parameters + * @param {string} url to append + * @param {object} params to append to url + * @return {string} url with appended params + */ +export const urlParams = (url, params) => { + let parts = []; + for (let key in params) { + parts.push( + [key, params[key]].join('=') + ); + } + return [url, parts.join('&')].join('?') +} + +/** + * construct a url with cache burster + * @param {string} url to append to + * @return {object} _cb key timestamp + */ +export const cacheBurstUrl = url => urlParams(url, cacheBurst()) + +/** + * @return {object} _cb as key with timestamp + */ +export const cacheBurst = () => ({ _cb: timestamp() }) + +/** + * From underscore.string library + * @BUG there is a bug here with the non-standard name start with _ + * @param {string} str string + * @return {string} dasherize string + */ +export const dasherize = str => ( + (str+'') + .trim() + .replace(/([A-Z])/g, '-$1') + .replace(/[-_\s]+/g, '-') + .toLowerCase() +) diff --git a/packages/jwt/src/client/utils/helpers.js b/packages/utils/src/jwt.js similarity index 51% rename from packages/jwt/src/client/utils/helpers.js rename to packages/utils/src/jwt.js index b01efabe6087555d8042e0f485484e3e9ab529f3..66897bd97edf01bc2e606d0b3dc5639095822a1b 100644 --- a/packages/jwt/src/client/utils/helpers.js +++ b/packages/utils/src/jwt.js @@ -1,11 +1,12 @@ -const { BASE64_FORMAT } = require('jsonql-constants'); +// ported from the jsonql-jwt +import { BASE64_FORMAT } from 'jsonql-constants' /** * create a buffer from string * @param {string} str to transform * @param {string} [format=BASE64_FORMAT] format to use * @return {buffer} tramsformed */ -function buff(str, format = BASE64_FORMAT) { +export function buff(str, format = BASE64_FORMAT) { if (Buffer.isBuffer(str)) { return str; } @@ -14,21 +15,14 @@ function buff(str, format = BASE64_FORMAT) { /** * encode in base64 string - * @param {*} in target + * @param {*} str target * @return {string} base64 encoded */ -const base64Encode = in => window.btoa(unescape(encodeURIComponent(str))) +export const base64Encode = str => window.btoa(unescape(encodeURIComponent(str))) /** * decode from base64 string - * @param {string} in base64 encoded string + * @param {string} json base64 encoded string * @return {*} decoded payload */ -const base64Decode = in => decodeURIComponent(escape(window.atob(str))) - - -export { - buff, - base64Encode, - base64Decode -} +export const base64Decode = json => decodeURIComponent(escape(window.atob(json))) diff --git a/packages/utils/src/koa.js b/packages/utils/src/koa.js index d51d7051c606f6b6c0f5f27d8390676b606200c3..a81df504314a9896b705f3e1e31d1c6310f5329c 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -1,11 +1,18 @@ // koa specific methods -import { CONTENT_TYPE } from 'jsonql-constants' -import jsonqlErrors from 'jsonql-errors' +import { CONTENT_TYPE, SUCCESS_STATUS, FORBIDDEN_STATUS } from 'jsonql-constants' +// fix the default is not export by module error +import * as jsonqlErrors from 'jsonql-errors' +import { + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError +} from './middleware' +import { dasherize } from './generic' - - -const SUCCESS_STATE = 200; -const FORBIDDEN_STATE = 403; /** * @TODO need to be more flexible * @param {object} ctx koa @@ -47,7 +54,7 @@ export const handleOutput = function(opts) { return function(ctx, body) { ctx.size = getDocLen(body) ctx.type = opts.contentType; - ctx.status = SUCCESS_STATE; + ctx.status = SUCCESS_STATUS; ctx.body = body; } } @@ -61,7 +68,7 @@ export const handleOutput = function(opts) { export const handleHtmlOutput = function(ctx, body) { ctx.size = getDocLen(body) ctx.type = 'text/html'; - ctx.status = SUCCESS_STATE; + ctx.status = SUCCESS_STATUS; ctx.body = body + ''; // just make sure its string output } @@ -98,5 +105,5 @@ export const ctxErrorHandler = function(ctx, code, e, message = '') { * @return {undefined} nothing */ export const forbiddenHandler = (ctx, e) => ( - ctxErrorHandler(ctx, FORBIDDEN_STATE, e, 'JsonqlAuthorisationError') + ctxErrorHandler(ctx, FORBIDDEN_STATUS, e, 'JsonqlAuthorisationError') ) diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 0aed9d5da3c3ca0bdb1851674a83f57c4e20a2c0..5c7ee99e00e30dc0dfef99ddff3878253e99dc5b 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -1,36 +1,29 @@ // this is a collection of middleware methods // should be good to use in Koa or Express -const _ = require('lodash') -const { trim } = _; -const { +// const { trim } = require('lodash-es') +import fs from 'fs' +import { QUERY_NAME, MUTATION_NAME, API_REQUEST_METHODS, PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME, RESOLVER_PARAM_NAME , - QUERY_ARG_NAME -} = require('jsonql-constants') - -/** - * From underscore.string library - * @BUG there is a bug here with the non-standard name start with _ - * @param {string} str string - * @return {string} dasherize string - */ -const dasherize = str => ( - trim(str) - .replace(/([A-Z])/g, '-$1') - .replace(/[-_\s]+/g, '-') - .toLowerCase() -) + QUERY_ARG_NAME, + DATA_KEY, + ERROR_KEY, + INDEX_KEY, + EXT +} from 'jsonql-constants' +const DOT = '.' +import { isKeyInObject, timestamp, dasherize } from './generic' /** * Get document (string) byte length for use in header * @param {string} doc to calculate * @return {number} length */ -const getDocLen = doc => Buffer.byteLength(doc, 'utf8') +export const getDocLen = doc => Buffer.byteLength(doc, 'utf8') /** * The koa ctx object is not returning what it said on the documentation @@ -39,7 +32,7 @@ const getDocLen = doc => Buffer.byteLength(doc, 'utf8') * @param {string} type (optional) to check against * @return {mixed} Array or Boolean */ -const headerParser = (req, type) => { +export const headerParser = (req, type) => { try { const headers = req.headers.accept.split(',') if (type) { @@ -58,7 +51,7 @@ const headerParser = (req, type) => { * @param {string} type of header * @return {boolean} */ -const isHeaderPresent = (req, type) => { +export const isHeaderPresent = (req, type) => { const headers = headerParser(req, type) return !!headers.length; } @@ -68,7 +61,7 @@ const isHeaderPresent = (req, type) => { * @param {string} method of call * @return {mixed} false on failed */ -const getCallMethod = method => { +export const getCallMethod = method => { const [ POST, PUT ] = API_REQUEST_METHODS; switch (true) { case method === POST: @@ -81,25 +74,24 @@ const getCallMethod = method => { } /** - * @param {string} name - * @param {string} type - * @param {object} opts - * @return {function} + * @param {string} name of the resolver + * @param {string} type what type of resolver + * @param {object} opts options + * @return {function|boolean} the resolver or FALSE */ -const getPathToFn = function(name, type, opts) { +export const getPathToFn = function(name, type, opts) { const dir = opts.resolverDir; - const fileName = dasherize(name); + const fileName = dasherize(name) let paths = []; if (opts.contract && opts.contract[type] && opts.contract[type].path) { - paths.push(opts.contract[type].path); + paths.push(opts.contract[type].path) } - paths.push( join(dir, type, fileName, 'index.js') ) - paths.push( join(dir, type, fileName + '.js') ) - // paths.push( join(dir, fileName + '.js') ); + paths.push( join(dir, type, fileName, [INDEX_KEY, EXT].join(DOT) ) ) + paths.push( join(dir, type, [fileName, EXT].join(DOT) ) ) const ctn = paths.length; for (let i=0; i { - return JSON.stringify({ data: result }) +export const packResult = function(result) { + return JSON.stringify({ [DATA_KEY]: result }) } /** @@ -121,8 +113,19 @@ const packResult = result => { * @param {number} [statusCode=500] the original error code * @return {string} stringify error */ -const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { +export const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { return JSON.stringify({ - error: { detail, className, statusCode, message } + [ERROR_KEY]: { detail, className, statusCode, message } }) } + +// ported from http-client + +/** + * handle the return data + * @param {object} result return from server + * @return {object} strip the data part out, or if the error is presented + */ +export const resultHandler = result => ( + (isKeyInObject(result, DATA_KEY) && !isKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result +) diff --git a/packages/utils/src/obj-define-props.js b/packages/utils/src/obj-define-props.js new file mode 100644 index 0000000000000000000000000000000000000000..1fb0783acc750eae280c9ce65648493aebec4298 --- /dev/null +++ b/packages/utils/src/obj-define-props.js @@ -0,0 +1,18 @@ +/** + * this is essentially the same as the injectToFn + * but this will not allow overwrite and set the setter and getter + * @param {object} obj to get injected + * @param {string} name of the property + * @param {function} setter for set + * @param {function} getter for get + * @return {object} the injected obj + */ +export function provideSetGet(obj, name, setter, getter) { + if (Object.getOwnPropertyDescriptor(obj, name) === undefined) { + Object.defineProperty(obj, name, { + set: setter, + get: getter + }) + } + return obj +} diff --git a/packages/utils/src/params-api.js b/packages/utils/src/params-api.js index 64758db4c6bfe91daa9c66ed498c575d01c586c9..25a4c60fbac2552e46e96ad4d9edfcba5027c3fe 100644 --- a/packages/utils/src/params-api.js +++ b/packages/utils/src/params-api.js @@ -8,10 +8,13 @@ import { QUERY_ARG_NAME } from 'jsonql-constants' import { JsonqlValidationError } from 'jsonql-errors' - +/* +use lodash-es instead import isString from './string' -import { checkIsArray } from './array' +import { isArray } from './array' import { checkIsObject } from './object' +*/ +import { isString, isArray, isPlainObject } from 'lodash-es' // make sure it's an object const formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload; @@ -32,7 +35,7 @@ export function getNameFromPayload(payload) { * @return {object} formatted argument */ export function createQuery(resolverName, args = [], jsonp = false) { - if (isString(resolverName) && checkIsArray(args)) { + if (isString(resolverName) && isArray(args)) { let payload = { [QUERY_ARG_NAME]: args } if (jsonp === true) { return payload; @@ -80,8 +83,8 @@ export function createMutationStr(resolverName, payload, condition = {}, jsonp = * @return {object|boolean} false on failed */ export function getQueryFromArgs(resolverName, payload) { - if (resolverName && checkIsObject(payload)) { - const args = payload[resolverName]; + if (resolverName && isPlainObject(payload)) { + const args = payload[resolverName] if (args[QUERY_ARG_NAME]) { return { [RESOLVER_PARAM_NAME]: resolverName, @@ -92,15 +95,25 @@ export function getQueryFromArgs(resolverName, payload) { return false; } +/** + * Share function so no repeat + * @param {object} payload the payload from client + * @param {function} processor the last get result method + * @return {*} result processed result + */ +function processPayload(payload, processor) { + const p = formatPayload(payload) + const resolverName = getNameFromPayload(p) + return Reflect.apply(processor, null, [resolverName, p]) +} + /** * extra the payload back * @param {*} payload from http call * @return {object} resolverName and args */ export function getQueryFromPayload(payload) { - const p = formatPayload(payload); - const resolverName = getNameFromPayload(p) - const result = getQueryFromArgs(resolverName, p) + const result = processPayload(payload, getQueryFromArgs) if (result !== false) { return result; } @@ -114,7 +127,7 @@ export function getQueryFromPayload(payload) { * @return {object|boolean} false on failed */ export function getMutationFromArgs(resolverName, payload) { - if (resolverName && checkIsObject(payload)) { + if (resolverName && isPlainObject(payload)) { const args = payload[resolverName] if (args) { return { @@ -132,9 +145,8 @@ export function getMutationFromArgs(resolverName, payload) { * @return {object} resolverName, payload, conditon */ export function getMutationFromPayload(payload) { - const p = formatPayload(payload); - const resolverName = getNameFromPayload(p) - const result = getMutationFromArgs(resolverName, p) + const result = processPayload(payload, getMutationFromArgs) + if (result !== false) { return result; } diff --git a/packages/jwt/tests/client-utils.test.js b/packages/utils/tests/client-utils.test.js similarity index 99% rename from packages/jwt/tests/client-utils.test.js rename to packages/utils/tests/client-utils.test.js index 6113ea9f96d52f42140c99d86ed05ad9a0d10183..4119182389b16d5ea1420b170db841cdc36666e4 100644 --- a/packages/jwt/tests/client-utils.test.js +++ b/packages/utils/tests/client-utils.test.js @@ -6,7 +6,6 @@ const fsx = require('fs-extra') const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract.json')) - test('It should able to give me two list from the contract', t => { const { size, nspSet, publicNamespace } = groupByNamespace(contract) diff --git a/packages/utils/tests/construct.test.js b/packages/utils/tests/construct.test.js new file mode 100644 index 0000000000000000000000000000000000000000..998a0367d75c35499a4a808ede022c3308000de1 --- /dev/null +++ b/packages/utils/tests/construct.test.js @@ -0,0 +1,21 @@ +// this is ported back from jsonql-params-validator +const test = require('ava') +const { isContract, isKeyInObject } = require('../main') + +test("It should able to check if an object is contract or not", t => { + + t.false(isContract('contract')) + t.false(isContract([])) + t.false(isContract({})) + t.true(isContract({query: {getSomething: {}}})) +}) + +test("Test isKeyInObject is exported or not", t => { + const client = {query: {}, mutation: false, socket: null}; + + t.true(isKeyInObject(client, 'mutation')) + t.true(isKeyInObject(client, 'socket')) + + t.false(isKeyInObject(client, 'auth')) + +}) diff --git a/packages/utils/tests/fixtures/contract.json b/packages/utils/tests/fixtures/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..72510498a1edea8f1eb2f2f5ea6a9970c66d8ba6 --- /dev/null +++ b/packages/utils/tests/fixtures/contract.json @@ -0,0 +1,111 @@ +{ + "query": {}, + "mutation": {}, + "auth": {}, + "timestamp": 1560348254, + "socket": { + "continuous": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/continuous.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "a message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "a message with timestamp" + } + ] + }, + "pinging": { + "namespace": "jsonql/public", + "public": true, + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/public/pinging.js", + "description": false, + "params": [ + { + "type": [ + "string" + ], + "name": "msg", + "description": "message" + } + ], + "returns": [ + { + "type": [ + "string" + ], + "description": "reply message based on your message" + } + ] + }, + "sendExtraMsg": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/send-extra-msg.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "x", + "description": "a number for process" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "x + ?" + } + ] + }, + "simple": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/simple.js", + "description": false, + "params": [ + { + "type": [ + "number" + ], + "name": "i", + "description": "a number" + } + ], + "returns": [ + { + "type": [ + "number" + ], + "description": "a number + 1;" + } + ] + }, + "throwError": { + "namespace": "jsonql/private", + "file": "/home/joel/projects/open-source/jsonqltools/packages/ws-client/tests/fixtures/resolvers/socket/throw-error.js", + "description": "Testing the throw error", + "params": [], + "returns": [ + { + "type": [ + "any" + ], + "description": "just throw" + } + ] + } + } +} diff --git a/packages/utils/tests/fn.test.js b/packages/utils/tests/fn.test.js new file mode 100644 index 0000000000000000000000000000000000000000..b6a2766f2423ad5b28729a17df8d3c3354d22cfa --- /dev/null +++ b/packages/utils/tests/fn.test.js @@ -0,0 +1,8 @@ +// just general test to make sure all the functions are presented before publish +const test = require('ava') +const utilFns = require('../main') + +test(`It should have certain functions in the export`, t => { + + t.truthy(utilFns.groupByNamespace) +}) diff --git a/packages/validator/tests/params-api.test.js b/packages/utils/tests/params-api.test.js similarity index 97% rename from packages/validator/tests/params-api.test.js rename to packages/utils/tests/params-api.test.js index 110dde0f13469f6d8ab643ef7340cf9bcdabb859..854fb0acb9b5be1b343484c9469ffae36681d805 100644 --- a/packages/validator/tests/params-api.test.js +++ b/packages/utils/tests/params-api.test.js @@ -7,7 +7,7 @@ const { getQueryFromArgs, getMutationFromArgs, getNameFromPayload -} = require('../dist/jsonql-params-validator.cjs') +} = require('../src/params-api') const { PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME, RESOLVER_PARAM_NAME } = require('jsonql-constants') const debug = require('debug')('jsonql:params-api') import { JsonqlValidationError } from 'jsonql-errors' diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js b/packages/validator/dist/jsonql-params-validator.cjs.js index c4e50fb09c91cda4400efdeaaf931fac85519be1..8f5db377f6424c16ffb50eb561542c7f2f3e670f 100644 --- a/packages/validator/dist/jsonql-params-validator.cjs.js +++ b/packages/validator/dist/jsonql-params-validator.cjs.js @@ -1,2 +1,2 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;function getRawTag(e){var r=hasOwnProperty.call(e,symToStringTag),t=e[symToStringTag];try{var a=!(e[symToStringTag]=void 0)}catch(e){}var n=nativeObjectToString.call(e);return a&&(r?e[symToStringTag]=t:delete e[symToStringTag]),n}var objectProto$1=Object.prototype,nativeObjectToString$1=objectProto$1.toString;function objectToString(e){return nativeObjectToString$1.call(e)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag$1=Symbol?Symbol.toStringTag:void 0;function baseGetTag(e){return null==e?void 0===e?undefinedTag:nullTag:symToStringTag$1&&symToStringTag$1 in Object(e)?getRawTag(e):objectToString(e)}function isObjectLike(e){return null!=e&&"object"==typeof e}var symbolTag="[object Symbol]";function isSymbol(e){return"symbol"==typeof e||isObjectLike(e)&&baseGetTag(e)==symbolTag}function arrayMap(e,r){for(var t=-1,a=null==e?0:e.length,n=Array(a);++t=HOT_COUNT)return arguments[0]}else a=0;return t.apply(void 0,arguments)}}function constant(e){return function(){return e}}var defineProperty=function(){try{var e=getNative(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),baseSetToString=defineProperty?function(e,r){return defineProperty(e,"toString",{configurable:!0,enumerable:!1,value:constant(r),writable:!0})}:identity,setToString=shortOut(baseSetToString);function baseFindIndex(e,r,t,a){for(var n=e.length,o=t+(a?1:-1);a?o--:++o>>0,r>>>=0;for(var o=Array(n);++a",NO_STATUS_CODE=-1,ARGS_NOT_ARRAY_ERR="args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)",PARAMS_NOT_ARRAY_ERR="params is not an array! Did something gone wrong when you generate the contract.json?",EXCEPTION_CASE_ERR="Could not understand your arguments and parameter structure!",DEFAULT_TYPE$1=DEFAULT_TYPE,ARRAY_TYPE_LFT$1=ARRAY_TYPE_LFT,ARRAY_TYPE_RGT$1=ARRAY_TYPE_RGT,TYPE_KEY$1=TYPE_KEY,OPTIONAL_KEY$1=OPTIONAL_KEY,ENUM_KEY$1=ENUM_KEY,ARGS_KEY$1=ARGS_KEY,CHECKER_KEY$1=CHECKER_KEY,ALIAS_KEY$1=ALIAS_KEY,ARRAY_TYPE$1=ARRAY_TYPE,OBJECT_TYPE$1=OBJECT_TYPE,STRING_TYPE$1=STRING_TYPE,BOOLEAN_TYPE$1=BOOLEAN_TYPE,NUMBER_TYPE$1=NUMBER_TYPE,KEY_WORD$1=KEY_WORD,OR_SEPERATOR$1=OR_SEPERATOR,combineFn=function(e){switch(e){case NUMBER_TYPE$1:return checkIsNumber;case STRING_TYPE$1:return checkIsString;case BOOLEAN_TYPE$1:return checkIsBoolean;default:return checkIsAny}},checkIsArray=function(e,r){return void 0===r&&(r=""),!!isArray(e)&&(""===r||""===trim(r)||!(0t.filter(function(e){return!combineFn(e)(r)}).length)}).length:t.length>t.filter(function(e){return!checkIsArray(r,e)}).length},checkIsObject=function(r,e){if(void 0===e&&(e=null),isPlainObject(r)){if(!e)return!0;if(checkIsArray(e))return!e.filter(function(e){var t=r[e.name];return!(e.type.length>e.type.filter(function(e){var r;return!!isUndefined(t)||(!1!==(r=isArrayLike$1(e))?!arrayTypeHandler({arg:t},r):!combineFn(e)(t))}).length)}).length}return!1},objectTypeHandler=function(e){var r=e.arg,t=e.param,a=[r];return Array.isArray(t.keys)&&t.keys.length&&a.push(t.keys),checkIsObject.apply(null,a)},isBrowser=function(){try{if(window||document)return!0}catch(e){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(e){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).where=function(){return whereAmI()},e}(Error),JsonqlEnumError=function(t){function a(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=a.name,t.captureStackTrace&&t.captureStackTrace(this,a)}t&&(a.__proto__=t),(a.prototype=Object.create(t&&t.prototype)).constructor=a;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(a,e),a}(Error),JsonqlTypeError=function(t){function a(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=a.name,t.captureStackTrace&&t.captureStackTrace(this,a)}t&&(a.__proto__=t),(a.prototype=Object.create(t&&t.prototype)).constructor=a;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(a,e),a}(Error),JsonqlCheckerError=function(t){function a(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=a.name,t.captureStackTrace&&t.captureStackTrace(this,a)}t&&(a.__proto__=t),(a.prototype=Object.create(t&&t.prototype)).constructor=a;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(a,e),a}(Error),JsonqlValidationError=function(t){function a(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=a.name,Error.captureStackTrace&&Error.captureStackTrace(this,a)}t&&(a.__proto__=t),(a.prototype=Object.create(t&&t.prototype)).constructor=a;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(a,e),a}(JsonqlBaseError),JsonqlError=function(t){function a(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=a.name,Error.captureStackTrace&&Error.captureStackTrace(this,a)}t&&(a.__proto__=t),(a.prototype=Object.create(t&&t.prototype)).constructor=a;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(a,e),a}(JsonqlBaseError);function log(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,e)}catch(e){}}var optionalHandler=function(r){var e=r.arg,t=r.param;return!!notEmpty(e)&&!(t.type.length>t.type.filter(function(e){return validateHandler(e,r)}).length)},validateHandler=function(e,r){var t;switch(!0){case e===OBJECT_TYPE$1:return!objectTypeHandler(r);case e===ARRAY_TYPE$1:return!checkIsArray(r.arg);case!1!==(t=isArrayLike$1(e)):return!arrayTypeHandler(r,t);default:return!combineFn(e)(r.arg)}},getOptionalValue=function(e,r){return isUndefined(e)?!0!==r.optional||isUndefined(r.defaultvalue)?null:r.defaultvalue:e},normalizeArgs=function(t,n){if(!checkIsArray(n))throw new JsonqlError(PARAMS_NOT_ARRAY_ERR);if(0===n.length)return[];if(!checkIsArray(t))throw new JsonqlError(ARGS_NOT_ARRAY_ERR);switch(!0){case t.length==n.length:return log(1),t.map(function(e,r){return{arg:e,index:r,param:n[r]}});case!0===n[0].variable:log(2);var a=n[0].type;return t.map(function(e,r){return{arg:e,index:r,param:n[r]||{type:a,name:"_"}}});case t.lengthn.length:log(4);var o=n.length,i=[DEFAULT_TYPE$1];return t.map(function(e,r){var t=o<=r||!!n[r].optional,a=n[r]||{type:i,name:"_"+r};return{arg:t?getOptionalValue(e,a):e,index:r,param:a,optional:t}});default:throw log(5),new JsonqlError(EXCEPTION_CASE_ERR,{args:t,params:n})}},processReturn=function(e){return e.map(function(e){return e.arg})},validateSync=function(e,r,t){var a;void 0===t&&(t=!1);var n=normalizeArgs(e,r),o=n.filter(function(r){return!0===r.optional||!0===r.param.optional?optionalHandler(r):!(r.param.type.length>r.param.type.filter(function(e){return validateHandler(e,r)}).length)});return t?((a={})[ERROR_KEY]=o,a[DATA_KEY]=processReturn(n),a):o},validateAsync=function(a,n,o){return void 0===o&&(o=!1),new Promise(function(e,r){var t=validateSync(a,n,o);return o?t[ERROR_KEY].length?r(t[ERROR_KEY]):e(t[DATA_KEY]):t.length?r(t):e([])})},isInArray=function(e,r){return!!e.filter(function(e){return e===r}).length},checkKeyInObject=function(e,r){var t=Object.keys(e);return isInArray(t,r)},isEmpty=function(e){return!notEmpty(e)};function mapAliasConfigKeys(e,r){var t=omitBy(r,function(e,r){return!e[ALIAS_KEY$1]});return isEqual(t,{})?e:mapKeys(e,function(e,r){return findKey(t,function(e){return e.alias===r})||r})}function preservePristineValues(e,r){var t=mapAliasConfigKeys(e,r);return{pristineValues:mapValues(omitBy(r,function(e,r){return checkKeyInObject(t,r)}),function(e){return e.args}),checkAgainstAppProps:omitBy(r,function(e,r){return!checkKeyInObject(t,r)}),config:t}}function processConfigAction(n,e){return mapValues(e,function(e,r){var t,a;return isUndefined(n[r])||!0===e[OPTIONAL_KEY$1]&&isEmpty(n[r])?merge({},e,((t={})[KEY_WORD$1]=!0,t)):((a={})[ARGS_KEY$1]=n[r],a[TYPE_KEY$1]=e[TYPE_KEY$1],a[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1]||!1,a[ENUM_KEY$1]=e[ENUM_KEY$1]||!1,a[CHECKER_KEY$1]=e[CHECKER_KEY$1]||!1,a)})}function prepareArgsForValidation(e,r){var t=preservePristineValues(e,r),a=t.config,n=t.pristineValues;return[processConfigAction(a,t.checkAgainstAppProps),n]}var toArray=function(e){return checkIsArray(e)?e:[e]},inArray=function(e,r){return!!e.filter(function(e){return e===r}).length};function validateHandler$1(e,r){var t,a=[[e[ARGS_KEY$1]],[(t={},t[TYPE_KEY$1]=toArray(e[TYPE_KEY$1]),t[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1],t)]];return Reflect.apply(r,null,a)}var enumHandler=function(e,r){return!checkIsArray(r)||inArray(r,e)},checkerHandler=function(e,r){try{return!!isFunction(r)&&r.apply(null,[e])}catch(e){return!1}};function runValidationAction(a){return function(e,r){if(e[KEY_WORD$1])return e[ARGS_KEY$1];var t=validateHandler$1(e,a);if(t.length)throw log("runValidationAction",r,e),new JsonqlTypeError(r,t);if(!1!==e[ENUM_KEY$1]&&!enumHandler(e[ARGS_KEY$1],e[ENUM_KEY$1]))throw log(ENUM_KEY$1,e[ENUM_KEY$1]),new JsonqlEnumError(r);if(!1!==e[CHECKER_KEY$1]&&!checkerHandler(e[ARGS_KEY$1],e[CHECKER_KEY$1]))throw log(CHECKER_KEY$1,e[CHECKER_KEY$1]),new JsonqlCheckerError(r);return e[ARGS_KEY$1]}}function runValidation(e,r){var t=e[0],a=e[1],n=mapValues(t,runValidationAction(r));return merge(n,a)}var configToArgs=function(e,r){return Promise.resolve(prepareArgsForValidation(e,r))};function checkOptionsAsync(e,r,t,a){return void 0===e&&(e={}),configToArgs(e,r).then(function(e){return runValidation(e,a)}).then(function(e){return merge({},e,t)})}function checkOptionsSync(e,r,t,a){return void 0===e&&(e={}),merge(runValidation(prepareArgsForValidation(e,r),a),t)}function constructConfigFn(e,r,t,a,n,o){void 0===t&&(t=!1),void 0===a&&(a=!1),void 0===n&&(n=!1),void 0===o&&(o=!1);var i={};return i[ARGS_KEY]=e,i[TYPE_KEY]=r,!0===t&&(i[OPTIONAL_KEY]=!0),checkIsArray(a)&&(i[ENUM_KEY]=a),isFunction(n)&&(i[CHECKER_KEY]=n),isString(o)&&(i[ALIAS_KEY]=o),i}var createConfig=function(e,r,t){void 0===t&&(t={});var a=t[OPTIONAL_KEY],n=t[ENUM_KEY],o=t[CHECKER_KEY],i=t[ALIAS_KEY];return constructConfigFn.apply(null,[e,r,a,n,o,i])},JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.4 module: cjs",checkConfigAsync=function(a){return function(e,r,t){return void 0===t&&(t={}),checkOptionsAsync(e,r,t,a)}},checkConfig=function(a){return function(e,r,t){return void 0===t&&(t={}),checkOptionsSync(e,r,t,a)}};function checkIsContract(e){return checkIsObject(e)&&(checkKeyInObject(e,QUERY_NAME)||checkKeyInObject(e,MUTATION_NAME)||checkKeyInObject(e,SOCKET_NAME))}var formatPayload=function(e){return checkIsString(e)?JSON.parse(e):e};function getNameFromPayload(e){return Object.keys(e)[0]}function createQuery(e,r,t){var a;if(void 0===r&&(r=[]),void 0===t&&(t=!1),checkIsString(e)&&checkIsArray(r)){var n={};return n[QUERY_ARG_NAME]=r,!0===t?n:((a={})[e]=n,a)}throw new JsonqlValidationError("[createQuery] expect resolverName to be string and args to be array!",{resolverName:e,args:r})}function createQueryStr(e,r,t){return void 0===r&&(r=[]),void 0===t&&(t=!1),JSON.stringify(createQuery(e,r,t))}function createMutation(e,r,t,a){var n;void 0===t&&(t={}),void 0===a&&(a=!1);var o={};if(o[PAYLOAD_PARAM_NAME]=r,o[CONDITION_PARAM_NAME]=t,!0===a)return o;if(checkIsString(e))return(n={})[e]=o,n;throw new JsonqlValidationError("[createMutation] expect resolverName to be string!",{resolverName:e,payload:r,condition:t})}function createMutationStr(e,r,t,a){return void 0===t&&(t={}),void 0===a&&(a=!1),JSON.stringify(createMutation(e,r,t,a))}function getQueryFromArgs(e,r){var t;if(e&&checkIsObject(r)){var a=r[e];if(a[QUERY_ARG_NAME])return(t={})[RESOLVER_PARAM_NAME]=e,t[QUERY_ARG_NAME]=a[QUERY_ARG_NAME],t}return!1}function getQueryFromPayload(e){var r=formatPayload(e),t=getQueryFromArgs(getNameFromPayload(r),r);if(!1!==t)return t;throw new JsonqlValidationError("[getQueryArgs] Payload is malformed!",e)}function getMutationFromArgs(e,r){var t;if(e&&checkIsObject(r)){var a=r[e];if(a)return(t={})[RESOLVER_PARAM_NAME]=e,t[PAYLOAD_PARAM_NAME]=a[PAYLOAD_PARAM_NAME],t[CONDITION_PARAM_NAME]=a[CONDITION_PARAM_NAME],t}return!1}function getMutationFromPayload(e){var r=formatPayload(e),t=getMutationFromArgs(getNameFromPayload(r),r);if(!1!==t)return t;throw new JsonqlValidationError("[getMutationArgs] Payload is malformed!",e)}var isObject$1=checkIsObject,isAny=checkIsAny,isString$1=checkIsString,isBoolean$1=checkIsBoolean,isNumber$1=checkIsNumber,isArray$1=checkIsArray,isNotEmpty=notEmpty,normalizeArgs$1=normalizeArgs,validateSync$1=validateSync,validateAsync$1=validateAsync,JSONQL_PARAMS_VALIDATOR_INFO$1=JSONQL_PARAMS_VALIDATOR_INFO,createConfig$1=createConfig,constructConfig=constructConfigFn,checkConfigAsync$1=checkConfigAsync(validateSync),checkConfig$1=checkConfig(validateSync),inArray$1=isInArray,isKeyInObject=checkKeyInObject,isContract=checkIsContract,createQuery$1=createQuery,createQueryStr$1=createQueryStr,createMutation$1=createMutation,createMutationStr$1=createMutationStr,getQueryFromArgs$1=getQueryFromArgs,getQueryFromPayload$1=getQueryFromPayload,getMutationFromArgs$1=getMutationFromArgs,getMutationFromPayload$1=getMutationFromPayload,getNameFromPayload$1=getNameFromPayload;exports.JSONQL_PARAMS_VALIDATOR_INFO=JSONQL_PARAMS_VALIDATOR_INFO$1,exports.checkConfig=checkConfig$1,exports.checkConfigAsync=checkConfigAsync$1,exports.constructConfig=constructConfig,exports.createConfig=createConfig$1,exports.createMutation=createMutation$1,exports.createMutationStr=createMutationStr$1,exports.createQuery=createQuery$1,exports.createQueryStr=createQueryStr$1,exports.getMutationFromArgs=getMutationFromArgs$1,exports.getMutationFromPayload=getMutationFromPayload$1,exports.getNameFromPayload=getNameFromPayload$1,exports.getQueryFromArgs=getQueryFromArgs$1,exports.getQueryFromPayload=getQueryFromPayload$1,exports.inArray=inArray$1,exports.isAny=isAny,exports.isArray=isArray$1,exports.isBoolean=isBoolean$1,exports.isContract=isContract,exports.isKeyInObject=isKeyInObject,exports.isNotEmpty=isNotEmpty,exports.isNumber=isNumber$1,exports.isObject=isObject$1,exports.isString=isString$1,exports.normalizeArgs=normalizeArgs$1,exports.validateAsync=validateAsync$1,exports.validateSync=validateSync$1; +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("debug");var global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;function getRawTag(e){var r=hasOwnProperty.call(e,symToStringTag),t=e[symToStringTag];try{var n=!(e[symToStringTag]=void 0)}catch(e){}var o=nativeObjectToString.call(e);return n&&(r?e[symToStringTag]=t:delete e[symToStringTag]),o}var objectProto$1=Object.prototype,nativeObjectToString$1=objectProto$1.toString;function objectToString(e){return nativeObjectToString$1.call(e)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag$1=Symbol?Symbol.toStringTag:void 0;function baseGetTag(e){return null==e?void 0===e?undefinedTag:nullTag:symToStringTag$1&&symToStringTag$1 in Object(e)?getRawTag(e):objectToString(e)}function isObjectLike(e){return null!=e&&"object"==typeof e}var symbolTag="[object Symbol]";function isSymbol(e){return"symbol"==typeof e||isObjectLike(e)&&baseGetTag(e)==symbolTag}function arrayMap(e,r){for(var t=-1,n=null==e?0:e.length,o=Array(n);++t=HOT_COUNT)return arguments[0]}else n=0;return t.apply(void 0,arguments)}}function constant(e){return function(){return e}}var defineProperty=function(){try{var e=getNative(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),baseSetToString=defineProperty?function(e,r){return defineProperty(e,"toString",{configurable:!0,enumerable:!1,value:constant(r),writable:!0})}:identity,setToString=shortOut(baseSetToString);function baseFindIndex(e,r,t,n){for(var o=e.length,a=t+(n?1:-1);n?a--:++a>>0,r>>>=0;for(var a=Array(o);++n",NO_STATUS_CODE=-1,ARGS_NOT_ARRAY_ERR="args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)",PARAMS_NOT_ARRAY_ERR="params is not an array! Did something gone wrong when you generate the contract.json?",EXCEPTION_CASE_ERR="Could not understand your arguments and parameter structure!",DEFAULT_TYPE$1=DEFAULT_TYPE,ARRAY_TYPE_LFT$1=ARRAY_TYPE_LFT,ARRAY_TYPE_RGT$1=ARRAY_TYPE_RGT,TYPE_KEY$1=TYPE_KEY,OPTIONAL_KEY$1=OPTIONAL_KEY,ENUM_KEY$1=ENUM_KEY,ARGS_KEY$1=ARGS_KEY,CHECKER_KEY$1=CHECKER_KEY,ALIAS_KEY$1=ALIAS_KEY,ARRAY_TYPE$1=ARRAY_TYPE,OBJECT_TYPE$1=OBJECT_TYPE,STRING_TYPE$1=STRING_TYPE,BOOLEAN_TYPE$1=BOOLEAN_TYPE,NUMBER_TYPE$1=NUMBER_TYPE,KEY_WORD$1=KEY_WORD,OR_SEPERATOR$1=OR_SEPERATOR,combineFn=function(e){switch(e){case NUMBER_TYPE$1:return checkIsNumber;case STRING_TYPE$1:return checkIsString;case BOOLEAN_TYPE$1:return checkIsBoolean;default:return checkIsAny}},checkIsArray=function(e,r){return void 0===r&&(r=""),!!isArray(e)&&(""===r||""===trim(r)||!(0t.filter(function(e){return!combineFn(e)(r)}).length)}).length:t.length>t.filter(function(e){return!checkIsArray(r,e)}).length},checkIsObject=function(r,e){if(void 0===e&&(e=null),isPlainObject(r)){if(!e)return!0;if(checkIsArray(e))return!e.filter(function(e){var t=r[e.name];return!(e.type.length>e.type.filter(function(e){var r;return!!isUndefined(t)||(!1!==(r=isArrayLike$1(e))?!arrayTypeHandler({arg:t},r):!combineFn(e)(t))}).length)}).length}return!1},objectTypeHandler=function(e){var r=e.arg,t=e.param,n=[r];return Array.isArray(t.keys)&&t.keys.length&&n.push(t.keys),checkIsObject.apply(null,n)},isBrowser=function(){try{if(window||document)return!0}catch(e){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(e){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).where=function(){return whereAmI()},e}(Error),JsonqlEnumError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(n,e),n}(Error),JsonqlTypeError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(n,e),n}(Error),JsonqlCheckerError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(n,e),n}(Error),JsonqlError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,Error.captureStackTrace&&Error.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return NO_STATUS_CODE},Object.defineProperties(n,e),n}(JsonqlBaseError);function log(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,e)}catch(e){}}var optionalHandler=function(r){var e=r.arg,t=r.param;return!!notEmpty(e)&&!(t.type.length>t.type.filter(function(e){return validateHandler(e,r)}).length)},validateHandler=function(e,r){var t;switch(!0){case e===OBJECT_TYPE$1:return!objectTypeHandler(r);case e===ARRAY_TYPE$1:return!checkIsArray(r.arg);case!1!==(t=isArrayLike$1(e)):return!arrayTypeHandler(r,t);default:return!combineFn(e)(r.arg)}},getOptionalValue=function(e,r){return isUndefined(e)?!0!==r.optional||isUndefined(r.defaultvalue)?null:r.defaultvalue:e},normalizeArgs=function(t,o){if(!checkIsArray(o))throw new JsonqlError(PARAMS_NOT_ARRAY_ERR);if(0===o.length)return[];if(!checkIsArray(t))throw new JsonqlError(ARGS_NOT_ARRAY_ERR);switch(!0){case t.length==o.length:return log(1),t.map(function(e,r){return{arg:e,index:r,param:o[r]}});case!0===o[0].variable:log(2);var n=o[0].type;return t.map(function(e,r){return{arg:e,index:r,param:o[r]||{type:n,name:"_"}}});case t.lengtho.length:log(4);var a=o.length,i=[DEFAULT_TYPE$1];return t.map(function(e,r){var t=a<=r||!!o[r].optional,n=o[r]||{type:i,name:"_"+r};return{arg:t?getOptionalValue(e,n):e,index:r,param:n,optional:t}});default:throw log(5),new JsonqlError(EXCEPTION_CASE_ERR,{args:t,params:o})}},processReturn=function(e){return e.map(function(e){return e.arg})},validateSync=function(e,r,t){var n;void 0===t&&(t=!1);var o=normalizeArgs(e,r),a=o.filter(function(r){return!0===r.optional||!0===r.param.optional?optionalHandler(r):!(r.param.type.length>r.param.type.filter(function(e){return validateHandler(e,r)}).length)});return t?((n={})[ERROR_KEY]=a,n[DATA_KEY]=processReturn(o),n):a},validateAsync=function(n,o,a){return void 0===a&&(a=!1),new Promise(function(e,r){var t=validateSync(n,o,a);return a?t[ERROR_KEY].length?r(t[ERROR_KEY]):e(t[DATA_KEY]):t.length?r(t):e([])})},inArray=function(e,r){return!!e.filter(function(e){return e===r}).length},isKeyInObject=function(e,r){var t=Object.keys(e);return inArray(t,r)},lookup=[],revLookup=[],Arr="undefined"!=typeof Uint8Array?Uint8Array:Array,inited=!1;function init(){inited=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,t=e.length;r>16&255,a[s++]=n>>8&255,a[s++]=255&n;return 2==o?(n=revLookup[e.charCodeAt(r)]<<2|revLookup[e.charCodeAt(r+1)]>>4,a[s++]=255&n):1==o&&(n=revLookup[e.charCodeAt(r)]<<10|revLookup[e.charCodeAt(r+1)]<<4|revLookup[e.charCodeAt(r+2)]>>2,a[s++]=n>>8&255,a[s++]=255&n),a}function tripletToBase64(e){return lookup[e>>18&63]+lookup[e>>12&63]+lookup[e>>6&63]+lookup[63&e]}function encodeChunk(e,r,t){for(var n,o=[],a=r;a>2],o+=lookup[r<<4&63],o+="=="):2==n&&(r=(e[t-2]<<8)+e[t-1],o+=lookup[r>>10],o+=lookup[r>>4&63],o+=lookup[r<<2&63],o+="="),a.push(o),a.join("")}function read(e,r,t,n,o){var a,i,s=8*o-n-1,u=(1<>1,c=-7,l=t?o-1:0,h=t?-1:1,p=e[r+l];for(l+=h,a=p&(1<<-c)-1,p>>=-c,c+=s;0>=-c,c+=n;0>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-1,g=n?1:-1,y=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(s=isNaN(r)?1:0,i=c):(i=Math.floor(Math.log(r)/Math.LN2),r*(u=Math.pow(2,-i))<1&&(i--,u*=2),2<=(r+=1<=i+l?h/u:h*Math.pow(2,1-l))*u&&(i++,u/=2),c<=i+l?(s=0,i=c):1<=i+l?(s=(r*u-1)*Math.pow(2,o),i+=l):(s=r*Math.pow(2,l-1)*Math.pow(2,o),i=0));8<=o;e[t+p]=255&s,p+=g,s/=256,o-=8);for(i=i<=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|e}function internalIsBuffer(e){return!(null==e||!e._isBuffer)}function byteLength(e,r){if(internalIsBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var t=e.length;if(0===t)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return t;case"utf8":case"utf-8":case void 0:return utf8ToBytes(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*t;case"hex":return t>>>1;case"base64":return base64ToBytes(e).length;default:if(n)return utf8ToBytes(e).length;r=(""+r).toLowerCase(),n=!0}}function slowToString(e,r,t){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===t||t>this.length)&&(t=this.length),t<=0)return"";if((t>>>=0)<=(r>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return hexSlice(this,r,t);case"utf8":case"utf-8":return utf8Slice(this,r,t);case"ascii":return asciiSlice(this,r,t);case"latin1":case"binary":return latin1Slice(this,r,t);case"base64":return base64Slice(this,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,r,t);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function swap(e,r,t){var n=e[r];e[r]=e[t],e[t]=n}function bidirectionalIndexOf(e,r,t,n,o){if(0===e.length)return-1;if("string"==typeof t?(n=t,t=0):2147483647=e.length){if(o)return-1;t=e.length-1}else if(t<0){if(!o)return-1;t=0}if("string"==typeof r&&(r=Buffer$2.from(r,n)),internalIsBuffer(r))return 0===r.length?-1:arrayIndexOf(e,r,t,n,o);if("number"==typeof r)return r&=255,Buffer$2.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,r,t):Uint8Array.prototype.lastIndexOf.call(e,r,t):arrayIndexOf(e,[r],t,n,o);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(e,r,t,n,o){var a,i=1,s=e.length,u=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||r.length<2)return-1;s/=i=2,u/=2,t/=2}function f(e,r){return 1===i?e[r]:e.readUInt16BE(r*i)}if(o){var c=-1;for(a=t;a>>10&1023|55296),c=56320|1023&c),n.push(c),o+=l}return decodeCodePointsArray(n)}Buffer$2.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer$2.poolSize=8192,Buffer$2._augment=function(e){return e.__proto__=Buffer$2.prototype,e},Buffer$2.from=function(e,r,t){return from(null,e,r,t)},Buffer$2.TYPED_ARRAY_SUPPORT&&(Buffer$2.prototype.__proto__=Uint8Array.prototype,Buffer$2.__proto__=Uint8Array),Buffer$2.alloc=function(e,r,t){return alloc(null,e,r,t)},Buffer$2.allocUnsafe=function(e){return allocUnsafe$1(null,e)},Buffer$2.allocUnsafeSlow=function(e){return allocUnsafe$1(null,e)},Buffer$2.isBuffer=isBuffer$1,Buffer$2.compare=function(e,r){if(!internalIsBuffer(e)||!internalIsBuffer(r))throw new TypeError("Arguments must be Buffers");if(e===r)return 0;for(var t=e.length,n=r.length,o=0,a=Math.min(t,n);or&&(e+=" ... ")),""},Buffer$2.prototype.compare=function(e,r,t,n,o){if(!internalIsBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===t&&(t=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),r<0||t>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(o<=n&&t<=r)return 0;if(o<=n)return-1;if(t<=r)return 1;if(this===e)return 0;for(var a=(o>>>=0)-(n>>>=0),i=(t>>>=0)-(r>>>=0),s=Math.min(a,i),u=this.slice(n,o),f=e.slice(r,t),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n=n||"utf8";for(var a=!1;;)switch(n){case"hex":return hexWrite(this,e,r,t);case"utf8":case"utf-8":return utf8Write(this,e,r,t);case"ascii":return asciiWrite(this,e,r,t);case"latin1":case"binary":return latin1Write(this,e,r,t);case"base64":return base64Write(this,e,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,e,r,t);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},Buffer$2.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(e){var r=e.length;if(r<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,e);for(var t="",n=0;ne.length)throw new RangeError("Index out of range")}function objectWriteUInt16(e,r,t,n){r<0&&(r=65535+r+1);for(var o=0,a=Math.min(e.length-t,2);o>>8*(n?o:1-o)}function objectWriteUInt32(e,r,t,n){r<0&&(r=4294967295+r+1);for(var o=0,a=Math.min(e.length-t,4);o>>8*(n?o:3-o)&255}function checkIEEE754(e,r,t,n,o,a){if(t+n>e.length)throw new RangeError("Index out of range");if(t<0)throw new RangeError("Index out of range")}function writeFloat(e,r,t,n,o){return o||checkIEEE754(e,r,t,4),write(e,r,t,n,23,4),t+4}function writeDouble(e,r,t,n,o){return o||checkIEEE754(e,r,t,8),write(e,r,t,n,52,8),t+8}Buffer$2.prototype.slice=function(e,r){var t,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeUInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeUInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r+3]=e>>>24,this[r+2]=e>>>16,this[r+1]=e>>>8,this[r]=255&e):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeUInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeIntLE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=0,i=1,s=0;for(this[r]=255&e;++a>0)-s&255;return r+t},Buffer$2.prototype.writeIntBE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=t-1,i=1,s=0;for(this[r+a]=255&e;0<=--a&&(i*=256);)e<0&&0===s&&0!==this[r+a+1]&&(s=1),this[r+a]=(e/i>>0)-s&255;return r+t},Buffer$2.prototype.writeInt8=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,1,127,-128),Buffer$2.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[r]=255&e,r+1},Buffer$2.prototype.writeInt16LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8,this[r+2]=e>>>16,this[r+3]=e>>>24):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeFloatLE=function(e,r,t){return writeFloat(this,e,r,!0,t)},Buffer$2.prototype.writeFloatBE=function(e,r,t){return writeFloat(this,e,r,!1,t)},Buffer$2.prototype.writeDoubleLE=function(e,r,t){return writeDouble(this,e,r,!0,t)},Buffer$2.prototype.writeDoubleBE=function(e,r,t){return writeDouble(this,e,r,!1,t)},Buffer$2.prototype.copy=function(e,r,t,n){if(t=t||0,n||0===n||(n=this.length),r>=e.length&&(r=e.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-r>>=0,t=void 0===t?this.length:t>>>0,"number"==typeof(e=e||0))for(a=r;a>6|192,63&t|128)}else if(t<65536){if((r-=3)<0)break;a.push(t>>12|224,t>>6&63|128,63&t|128)}else{if(!(t<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;a.push(t>>18|240,t>>12&63|128,t>>6&63|128,63&t|128)}}return a}function asciiToBytes(e){for(var r=[],t=0;t>8,o=t%256,a.push(o),a.push(n);return a}function base64ToBytes(e){return toByteArray(base64clean(e))}function blitBuffer(e,r,t,n){for(var o=0;o=r.length||o>=e.length);++o)r[o+t]=e[o];return o}function isnan(e){return e!=e}function isBuffer$1(e){return null!=e&&(!!e._isBuffer||isFastBuffer(e)||isSlowBuffer(e))}function isFastBuffer(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function isSlowBuffer(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&isFastBuffer(e.slice(0,0))}global$1.setTimeout,global$1.clearTimeout;var performance=global$1.performance||{},performanceNow=performance.now||performance.mozNow||performance.msNow||performance.oNow||performance.webkitNow||function(){return(new Date).getTime()},isEmpty=function(e){return!notEmpty(e)};function mapAliasConfigKeys(e,r){var t=omitBy(r,function(e,r){return!e[ALIAS_KEY$1]});return isEqual(t,{})?e:mapKeys(e,function(e,r){return findKey(t,function(e){return e.alias===r})||r})}function preservePristineValues(e,r){var t=mapAliasConfigKeys(e,r);return{pristineValues:mapValues(omitBy(r,function(e,r){return isKeyInObject(t,r)}),function(e){return e.args}),checkAgainstAppProps:omitBy(r,function(e,r){return!isKeyInObject(t,r)}),config:t}}function processConfigAction(o,e){return mapValues(e,function(e,r){var t,n;return isUndefined(o[r])||!0===e[OPTIONAL_KEY$1]&&isEmpty(o[r])?merge({},e,((t={})[KEY_WORD$1]=!0,t)):((n={})[ARGS_KEY$1]=o[r],n[TYPE_KEY$1]=e[TYPE_KEY$1],n[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1]||!1,n[ENUM_KEY$1]=e[ENUM_KEY$1]||!1,n[CHECKER_KEY$1]=e[CHECKER_KEY$1]||!1,n)})}function prepareArgsForValidation(e,r){var t=preservePristineValues(e,r),n=t.config,o=t.pristineValues;return[processConfigAction(n,t.checkAgainstAppProps),o]}var toArray=function(e){return checkIsArray(e)?e:[e]},inArray$1=function(e,r){return!!e.filter(function(e){return e===r}).length};function validateHandler$1(e,r){var t,n=[[e[ARGS_KEY$1]],[(t={},t[TYPE_KEY$1]=toArray(e[TYPE_KEY$1]),t[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1],t)]];return Reflect.apply(r,null,n)}var enumHandler=function(e,r){return!checkIsArray(r)||inArray$1(r,e)},checkerHandler=function(e,r){try{return!!isFunction(r)&&r.apply(null,[e])}catch(e){return!1}};function runValidationAction(n){return function(e,r){if(e[KEY_WORD$1])return e[ARGS_KEY$1];var t=validateHandler$1(e,n);if(t.length)throw log("runValidationAction",r,e),new JsonqlTypeError(r,t);if(!1!==e[ENUM_KEY$1]&&!enumHandler(e[ARGS_KEY$1],e[ENUM_KEY$1]))throw log(ENUM_KEY$1,e[ENUM_KEY$1]),new JsonqlEnumError(r);if(!1!==e[CHECKER_KEY$1]&&!checkerHandler(e[ARGS_KEY$1],e[CHECKER_KEY$1]))throw log(CHECKER_KEY$1,e[CHECKER_KEY$1]),new JsonqlCheckerError(r);return e[ARGS_KEY$1]}}function runValidation(e,r){var t=e[0],n=e[1],o=mapValues(t,runValidationAction(r));return merge(o,n)}var configToArgs=function(e,r){return Promise.resolve(prepareArgsForValidation(e,r))};function checkOptionsAsync(e,r,t,n){return void 0===e&&(e={}),configToArgs(e,r).then(function(e){return runValidation(e,n)}).then(function(e){return merge({},e,t)})}function checkOptionsSync(e,r,t,n){return void 0===e&&(e={}),merge(runValidation(prepareArgsForValidation(e,r),n),t)}function constructConfigFn(e,r,t,n,o,a){void 0===t&&(t=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===a&&(a=!1);var i={};return i[ARGS_KEY]=e,i[TYPE_KEY]=r,!0===t&&(i[OPTIONAL_KEY]=!0),checkIsArray(n)&&(i[ENUM_KEY]=n),isFunction(o)&&(i[CHECKER_KEY]=o),isString(a)&&(i[ALIAS_KEY]=a),i}var createConfig=function(e,r,t){void 0===t&&(t={});var n=t[OPTIONAL_KEY],o=t[ENUM_KEY],a=t[CHECKER_KEY],i=t[ALIAS_KEY];return constructConfigFn.apply(null,[e,r,n,o,a,i])},JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.6 module: cjs",checkConfigAsync=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsAsync(e,r,t,n)}},checkConfig=function(n){return function(e,r,t){return void 0===t&&(t={}),checkOptionsSync(e,r,t,n)}},isObject$1=checkIsObject,isAny=checkIsAny,isString$1=checkIsString,isBoolean$1=checkIsBoolean,isNumber$1=checkIsNumber,isArray$2=checkIsArray,isNotEmpty=notEmpty,normalizeArgs$1=normalizeArgs,validateSync$1=validateSync,validateAsync$1=validateAsync,JSONQL_PARAMS_VALIDATOR_INFO$1=JSONQL_PARAMS_VALIDATOR_INFO,createConfig$1=createConfig,constructConfig=constructConfigFn,checkConfigAsync$1=checkConfigAsync(validateSync),checkConfig$1=checkConfig(validateSync);exports.JSONQL_PARAMS_VALIDATOR_INFO=JSONQL_PARAMS_VALIDATOR_INFO$1,exports.checkConfig=checkConfig$1,exports.checkConfigAsync=checkConfigAsync$1,exports.constructConfig=constructConfig,exports.createConfig=createConfig$1,exports.isAny=isAny,exports.isArray=isArray$2,exports.isBoolean=isBoolean$1,exports.isNotEmpty=isNotEmpty,exports.isNumber=isNumber$1,exports.isObject=isObject$1,exports.isString=isString$1,exports.normalizeArgs=normalizeArgs$1,exports.validateAsync=validateAsync$1,exports.validateSync=validateSync$1; //# sourceMappingURL=jsonql-params-validator.cjs.js.map diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js.map b/packages/validator/dist/jsonql-params-validator.cjs.js.map index 44a652f199b5203cbc07f3354b7eb7b3149e746b..29f1ab1ae8311b5c6881ba853b2e6308c5187321 100644 --- a/packages/validator/dist/jsonql-params-validator.cjs.js.map +++ b/packages/validator/dist/jsonql-params-validator.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-params-validator.cjs.js","sources":["../node_modules/rollup-plugin-node-globals/src/global.js"],"sourcesContent":["export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n"],"names":[],"mappings":"oEAAA"} \ No newline at end of file +{"version":3,"file":"jsonql-params-validator.cjs.js","sources":["../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/buffer-es6/isArray.js"],"sourcesContent":["export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n","var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"qFAAA,2tvCCAA"} \ No newline at end of file diff --git a/packages/validator/dist/jsonql-params-validator.umd.js b/packages/validator/dist/jsonql-params-validator.umd.js index d71077f02276751d94d0bd55c81ff73f82f3edfd..44e996a0d20a2a14d63ec53a97093c6dfc5b7b68 100644 --- a/packages/validator/dist/jsonql-params-validator.umd.js +++ b/packages/validator/dist/jsonql-params-validator.umd.js @@ -1,2 +1,2 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlParamsValidator={})}(this,function(t){"use strict";var r="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n="object"==typeof r&&r&&r.Object===Object&&r,e="object"==typeof self&&self&&self.Object===Object&&self,o=n||e||Function("return this")(),u=o.Symbol,i=Object.prototype,a=i.hasOwnProperty,c=i.toString,f=u?u.toStringTag:void 0;var l=Object.prototype.toString;var s="[object Null]",p="[object Undefined]",v=u?u.toStringTag:void 0;function h(t){return null==t?void 0===t?p:s:v&&v in Object(t)?function(t){var r=a.call(t,f),n=t[f];try{var e=!(t[f]=void 0)}catch(t){}var o=c.call(t);return e&&(r?t[f]=n:delete t[f]),o}(t):function(t){return l.call(t)}(t)}function y(t){return null!=t&&"object"==typeof t}var d="[object Symbol]";function g(t){return"symbol"==typeof t||y(t)&&h(t)==d}function b(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n>>0,r>>>=0;for(var u=Array(o);++e")){var r=t.replace(Ie,"").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1}function xe(t,n){var r=t.arg;return 1n.filter(function(t){return!Ee(t)(r)}).length)}).length:n.length>n.filter(function(t){return!Ye(r,t)}).length}function Te(){try{if(window||document)return!0}catch(t){}return!1}var Ne=function(t){return""!==Oe(t)&&se(t)},Fe="error",Me="payload",Ce="condition",$e="resolverName",Be="args",Re="optional",Ve="enumv",qe="checker",De="alias",Ie="array.<",Je="type",Le=Re,Qe=Ve,Ue="args",We=qe,Ge=De,Ke="continue",Ye=function(t,r){return void 0===r&&(r=""),!!_(t)&&(""===r||""===Oe(r)||!(0t.type.filter(function(t){var r;return!!he(n)||(!1!==(r=ze(t))?!xe({arg:n},r):!Ee(t)(n))}).length)}).length}return!1};function Xe(){return Te()?"browser":function(){try{if(!Te()&&r)return!0}catch(t){}return!1}()?"node":"unknown"}var Ze=function(n){function t(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t)}return n&&(t.__proto__=n),((t.prototype=Object.create(n&&n.prototype)).constructor=t).where=function(){return Xe()},t}(Error),to=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,t),e}(Error),ro=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,t),e}(Error),no=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,t),e}(Error),eo=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(e,t),e}(Ze),oo=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0},statusCode:{configurable:!0}};return t.name.get=function(){return"JsonqlError"},t.statusCode.get=function(){return-1},Object.defineProperties(e,t),e}(Ze);function uo(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}function io(t,r){return he(t)?!0!==r.optional||he(r.defaultvalue)?null:r.defaultvalue:t}function ao(n,o){if(!Ye(o))throw new oo("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===o.length)return[];if(!Ye(n))throw new oo("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case n.length==o.length:return uo(1),n.map(function(t,r){return{arg:t,index:r,param:o[r]}});case!0===o[0].variable:uo(2);var e=o[0].type;return n.map(function(t,r){return{arg:t,index:r,param:o[r]||{type:e,name:"_"}}});case n.lengtho.length:uo(4);var u=o.length,i=["any"];return n.map(function(t,r){var n=u<=r||!!o[r].optional,e=o[r]||{type:i,name:"_"+r};return{arg:n?io(t,e):t,index:r,param:e,optional:n}});default:throw uo(5),new oo("Could not understand your arguments and parameter structure!",{args:n,params:o})}}function co(t,r,n){var e;void 0===n&&(n=!1);var o=ao(t,r),u=o.filter(function(r){return!0===r.optional||!0===r.param.optional?function(r){var t=r.arg,n=r.param;return!!Ae(t)&&!(n.type.length>n.type.filter(function(t){return lo(t,r)}).length)}(r):!(r.param.type.length>r.param.type.filter(function(t){return lo(t,r)}).length)});return n?((e={})[Fe]=u,e.data=function(t){return t.map(function(t){return t.arg})}(o),e):u}function fo(t,r){return!!t.filter(function(t){return t===r}).length}var lo=function(t,r){var n;switch(!0){case"object"===t:return!function(t){var r=t.arg,n=t.param,e=[r];return Array.isArray(n.keys)&&n.keys.length&&e.push(n.keys),He.apply(null,e)}(r);case"array"===t:return!Ye(r.arg);case!1!==(n=ze(t)):return!xe(r,n);default:return!Ee(t)(r.arg)}},so=function(t,r){var n=Object.keys(t);return fo(n,r)},po=function(t){return!Ae(t)};function vo(t,r){var n=me(r,function(t,r){return!t[Ge]});return function(t,r){return Jn(t,r)}(n,{})?t:function(t,e){var o={};return e=re(e),oe(t,function(t,r,n){ut(o,e(t,r,n),t)}),o}(t,function(t,r){return function(t,r){return function(t,e,r){var o;return r(t,function(t,r,n){if(e(t,r,n))return o=r,!1}),o}(t,re(r),oe)}(n,function(t){return t.alias===r})||r})}function ho(t,r){var n=function(t,r){var n=vo(t,r);return{pristineValues:ye(me(r,function(t,r){return so(n,r)}),function(t){return t.args}),checkAgainstAppProps:me(r,function(t,r){return!so(n,r)}),config:n}}(t,r),e=n.config,o=n.pristineValues;return[function(o,t){return ye(t,function(t,r){var n,e;return he(o[r])||!0===t[Le]&&po(o[r])?ge({},t,((n={})[Ke]=!0,n)):((e={})[Ue]=o[r],e[Je]=t[Je],e[Le]=t[Le]||!1,e[Qe]=t[Qe]||!1,e[We]=t[We]||!1,e)})}(e,n.checkAgainstAppProps),o]}var yo=function(t){return Ye(t)?t:[t]};var go=function(t,r){return!Ye(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},bo=function(t,r){try{return!!x(r)&&r.apply(null,[t])}catch(t){return!1}};function _o(e){return function(t,r){if(t[Ke])return t[Ue];var n=function(t,r){var n,e=[[t[Ue]],[(n={},n[Je]=yo(t[Je]),n[Le]=t[Le],n)]];return Reflect.apply(r,null,e)}(t,e);if(n.length)throw uo("runValidationAction",r,t),new ro(r,n);if(!1!==t[Qe]&&!go(t[Ue],t[Qe]))throw uo(Qe,t[Qe]),new to(r);if(!1!==t[We]&&!bo(t[Ue],t[We]))throw uo(We,t[We]),new no(r);return t[Ue]}}function jo(t,r){var n=t[0],e=t[1],o=ye(n,_o(r));return ge(o,e)}function mo(t,r,n,e){return void 0===t&&(t={}),function(t,r){return Promise.resolve(ho(t,r))}(t,r).then(function(t){return jo(t,e)}).then(function(t){return ge({},t,n)})}function wo(t,r,n,e,o,u){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===u&&(u=!1);var i={};return i.args=t,i.type=r,!0===n&&(i[Re]=!0),Ye(e)&&(i[Ve]=e),x(o)&&(i[qe]=o),se(u)&&(i[De]=u),i}function Oo(t){return Ne(t)?JSON.parse(t):t}function Ao(t){return Object.keys(t)[0]}function So(t,r,n){var e;if(void 0===r&&(r=[]),void 0===n&&(n=!1),Ne(t)&&Ye(r)){var o={};return o[Be]=r,!0===n?o:((e={})[t]=o,e)}throw new eo("[createQuery] expect resolverName to be string and args to be array!",{resolverName:t,args:r})}function Po(t,r,n,e){var o;void 0===n&&(n={}),void 0===e&&(e=!1);var u={};if(u[Me]=r,u[Ce]=n,!0===e)return u;if(Ne(t))return(o={})[t]=u,o;throw new eo("[createMutation] expect resolverName to be string!",{resolverName:t,payload:r,condition:n})}function ko(t,r){var n;if(t&&He(r)){var e=r[t];if(e[Be])return(n={})[$e]=t,n[Be]=e[Be],n}return!1}function Eo(t,r){var n;if(t&&He(r)){var e=r[t];if(e)return(n={})[$e]=t,n[Me]=e[Me],n[Ce]=e[Ce],n}return!1}function zo(e,o,u){return void 0===u&&(u=!1),new Promise(function(t,r){var n=co(e,o,u);return u?n[Fe].length?r(n[Fe]):t(n.data):n.length?r(n):t([])})}function xo(t,r,n){void 0===n&&(n={});var e=n[Re],o=n[Ve],u=n[qe],i=n[De];return wo.apply(null,[t,r,e,o,u,i])}function To(t){return He(t)&&(so(t,"query")||so(t,"mutation")||so(t,"socket"))}function No(t,r,n){return void 0===r&&(r=[]),void 0===n&&(n=!1),JSON.stringify(So(t,r,n))}function Fo(t,r,n,e){return void 0===n&&(n={}),void 0===e&&(e=!1),JSON.stringify(Po(t,r,n,e))}function Mo(t){var r=Oo(t),n=ko(Ao(r),r);if(!1!==n)return n;throw new eo("[getQueryArgs] Payload is malformed!",t)}function Co(t){var r=Oo(t),n=Eo(Ao(r),r);if(!1!==n)return n;throw new eo("[getMutationArgs] Payload is malformed!",t)}var $o,Bo,Ro=He,Vo=ke,qo=Ne,Do=Pe,Io=Se,Jo=Ye,Lo=Ae,Qo=ao,Uo=co,Wo=wo,Go=($o=co,function(t,r,n){return void 0===n&&(n={}),mo(t,r,n,$o)}),Ko=(Bo=co,function(t,r,n){return void 0===n&&(n={}),function(t,r,n,e){return void 0===t&&(t={}),ge(jo(ho(t,r),e),n)}(t,r,n,Bo)}),Yo=fo,Ho=so,Xo=So,Zo=Po,tu=ko,ru=Eo,nu=Ao;t.JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.4 module: umd",t.checkConfig=Ko,t.checkConfigAsync=Go,t.constructConfig=Wo,t.createConfig=xo,t.createMutation=Zo,t.createMutationStr=Fo,t.createQuery=Xo,t.createQueryStr=No,t.getMutationFromArgs=ru,t.getMutationFromPayload=Co,t.getNameFromPayload=nu,t.getQueryFromArgs=tu,t.getQueryFromPayload=Mo,t.inArray=Yo,t.isAny=Vo,t.isArray=Jo,t.isBoolean=Do,t.isContract=To,t.isKeyInObject=Ho,t.isNotEmpty=Lo,t.isNumber=Io,t.isObject=Ro,t.isString=qo,t.normalizeArgs=Qo,t.validateAsync=zo,t.validateSync=Uo,Object.defineProperty(t,"__esModule",{value:!0})}); +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlParamsValidator={},t.debug)}(this,function(t,r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e="object"==typeof n&&n&&n.Object===Object&&n,o="object"==typeof self&&self&&self.Object===Object&&self,i=e||o||Function("return this")(),u=i.Symbol,a=Object.prototype,f=a.hasOwnProperty,c=a.toString,s=u?u.toStringTag:void 0;var h=Object.prototype.toString;var l="[object Null]",p="[object Undefined]",g=u?u.toStringTag:void 0;function v(t){return null==t?void 0===t?p:l:g&&g in Object(t)?function(t){var r=f.call(t,s),n=t[s];try{var e=!(t[s]=void 0)}catch(t){}var o=c.call(t);return e&&(r?t[s]=n:delete t[s]),o}(t):function(t){return h.call(t)}(t)}function y(t){return null!=t&&"object"==typeof t}var d="[object Symbol]";function b(t){return"symbol"==typeof t||y(t)&&v(t)==d}function w(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n>>0,r>>>=0;for(var i=Array(o);++e")){var r=t.replace(Ne,"").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1}function ke(t,n){var r=t.arg;return 1n.filter(function(t){return!Ue(t)(r)}).length)}).length:n.length>n.filter(function(t){return!Be(r,t)}).length}function Ye(r,t){if(void 0===t&&(t=null),Ar(r)){if(!t)return!0;if(Be(t))return!t.filter(function(t){var n=r[t.name];return!(t.type.length>t.type.filter(function(t){var r;return!!ve(n)||(!1!==(r=Ie(t))?!ke({arg:n},r):!Ue(t)(n))}).length)}).length}return!1}function Ce(){try{if(window||document)return!0}catch(t){}return!1}var xe="error",Me="optional",Le="enumv",ze="checker",De="alias",Ne="array.<",Fe="type",Ve=Me,$e=Le,qe="args",Je=ze,We=De,Ge="continue";function Qe(){return Ce()?"browser":function(){try{if(!Ce()&&n)return!0}catch(t){}return!1}()?"node":"unknown"}var Ze=function(n){function t(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t)}return n&&(t.__proto__=n),((t.prototype=Object.create(n&&n.prototype)).constructor=t).where=function(){return Qe()},t}(Error),He=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,t),e}(Error),Ke=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,t),e}(Error),Xe=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,t),e}(Error),to=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0},statusCode:{configurable:!0}};return t.name.get=function(){return"JsonqlError"},t.statusCode.get=function(){return-1},Object.defineProperties(e,t),e}(Ze);function ro(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}function no(t,r){return ve(t)?!0!==r.optional||ve(r.defaultvalue)?null:r.defaultvalue:t}function eo(n,o){if(!Be(o))throw new to("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===o.length)return[];if(!Be(n))throw new to("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case n.length==o.length:return ro(1),n.map(function(t,r){return{arg:t,index:r,param:o[r]}});case!0===o[0].variable:ro(2);var e=o[0].type;return n.map(function(t,r){return{arg:t,index:r,param:o[r]||{type:e,name:"_"}}});case n.lengtho.length:ro(4);var i=o.length,u=["any"];return n.map(function(t,r){var n=i<=r||!!o[r].optional,e=o[r]||{type:u,name:"_"+r};return{arg:n?no(t,e):t,index:r,param:e,optional:n}});default:throw ro(5),new to("Could not understand your arguments and parameter structure!",{args:n,params:o})}}function oo(t,r,n){var e;void 0===n&&(n=!1);var o=eo(t,r),i=o.filter(function(r){return!0===r.optional||!0===r.param.optional?function(r){var t=r.arg,n=r.param;return!!Oe(t)&&!(n.type.length>n.type.filter(function(t){return io(t,r)}).length)}(r):!(r.param.type.length>r.param.type.filter(function(t){return io(t,r)}).length)});return n?((e={})[xe]=i,e.data=function(t){return t.map(function(t){return t.arg})}(o),e):i}var io=function(t,r){var n;switch(!0){case"object"===t:return!function(t){var r=t.arg,n=t.param,e=[r];return Array.isArray(n.keys)&&n.keys.length&&e.push(n.keys),Ye.apply(null,e)}(r);case"array"===t:return!Be(r.arg);case!1!==(n=Ie(t)):return!ke(r,n);default:return!Ue(t)(r.arg)}},uo=function(t,r){return function(t,r){return!!t.filter(function(t){return t===r}).length}(Object.keys(t),r)},ao=[],fo=[],co="undefined"!=typeof Uint8Array?Uint8Array:Array,so=!1;function ho(){so=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,n=t.length;r>18&63]+ao[o>>12&63]+ao[o>>6&63]+ao[63&o]);return i.join("")}function po(t){var r;so||ho();for(var n=t.length,e=n%3,o="",i=[],u=0,a=n-e;u>2],o+=ao[r<<4&63],o+="=="):2==e&&(r=(t[n-2]<<8)+t[n-1],o+=ao[r>>10],o+=ao[r>>4&63],o+=ao[r<<2&63],o+="="),i.push(o),i.join("")}function go(t,r,n,e,o){var i,u,a=8*o-e-1,f=(1<>1,s=-7,h=n?o-1:0,l=n?-1:1,p=t[r+h];for(h+=l,i=p&(1<<-s)-1,p>>=-s,s+=a;0>=-s,s+=e;0>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=e?0:i-1,g=e?1:-1,v=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,u=s):(u=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-u))<1&&(u--,f*=2),2<=(r+=1<=u+h?l/f:l*Math.pow(2,1-h))*f&&(u++,f/=2),s<=u+h?(a=0,u=s):1<=u+h?(a=(r*f-1)*Math.pow(2,o),u+=h):(a=r*Math.pow(2,h-1)*Math.pow(2,o),u=0));8<=o;t[n+p]=255&a,p+=g,a/=256,o-=8);for(u=u<=wo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+wo().toString(16)+" bytes");return 0|t}function Ro(t){return!(null==t||!t._isBuffer)}function To(t,r){if(Ro(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var e=!1;;)switch(r){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Zo(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return Ho(t).length;default:if(e)return Zo(t).length;r=(""+r).toLowerCase(),e=!0}}function So(t,r,n){var e=t[r];t[r]=t[n],t[n]=e}function Uo(t,r,n,e,o){if(0===t.length)return-1;if("string"==typeof n?(e=n,n=0):2147483647=t.length){if(o)return-1;n=t.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof r&&(r=mo.from(r,e)),Ro(r))return 0===r.length?-1:Bo(t,r,n,e,o);if("number"==typeof r)return r&=255,mo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,n):Uint8Array.prototype.lastIndexOf.call(t,r,n):Bo(t,[r],n,e,o);throw new TypeError("val must be string, number or Buffer")}function Bo(t,r,n,e,o){var i,u=1,a=t.length,f=r.length;if(void 0!==e&&("ucs2"===(e=String(e).toLowerCase())||"ucs-2"===e||"utf16le"===e||"utf-16le"===e)){if(t.length<2||r.length<2)return-1;a/=u=2,f/=2,n/=2}function c(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(o){var s=-1;for(i=n;i>>10&1023|55296),s=56320|1023&s),e.push(s),o+=h}return function(t){var r=t.length;if(r<=xo)return String.fromCharCode.apply(String,t);var n="",e=0;for(;ethis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(r>>>=0))return"";for(t=t||"utf8";;)switch(t){case"hex":return zo(this,r,n);case"utf8":case"utf-8":return Co(this,r,n);case"ascii":return Mo(this,r,n);case"latin1":case"binary":return Lo(this,r,n);case"base64":return Yo(this,r,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Do(this,r,n);default:if(e)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),e=!0}}.apply(this,arguments)},mo.prototype.equals=function(t){if(!Ro(t))throw new TypeError("Argument must be a Buffer");return this===t||0===mo.compare(this,t)},mo.prototype.inspect=function(){var t="";return 0"},mo.prototype.compare=function(t,r,n,e,o){if(!Ro(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===n&&(n=t?t.length:0),void 0===e&&(e=0),void 0===o&&(o=this.length),r<0||n>t.length||e<0||o>this.length)throw new RangeError("out of range index");if(o<=e&&n<=r)return 0;if(o<=e)return-1;if(n<=r)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(e>>>=0),u=(n>>>=0)-(r>>>=0),a=Math.min(i,u),f=this.slice(e,o),c=t.slice(r,n),s=0;sthis.length)throw new RangeError("Attempt to write outside buffer bounds");e=e||"utf8";for(var i,u,a,f,c,s,h,l,p,g=!1;;)switch(e){case"hex":return Io(this,t,r,n);case"utf8":case"utf-8":return l=r,p=n,Ko(Zo(t,(h=this).length-l),h,l,p);case"ascii":return ko(this,t,r,n);case"latin1":case"binary":return ko(this,t,r,n);case"base64":return f=this,c=r,s=n,Ko(Ho(t),f,c,s);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return u=r,a=n,Ko(function(t,r){for(var n,e,o,i=[],u=0;u>8,o=n%256,i.push(o),i.push(e);return i}(t,(i=this).length-u),i,u,a);default:if(g)throw new TypeError("Unknown encoding: "+e);e=(""+e).toLowerCase(),g=!0}},mo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var xo=4096;function Mo(t,r,n){var e="";n=Math.min(t.length,n);for(var o=r;ot.length)throw new RangeError("Index out of range")}function Vo(t,r,n,e){r<0&&(r=65535+r+1);for(var o=0,i=Math.min(t.length-n,2);o>>8*(e?o:1-o)}function $o(t,r,n,e){r<0&&(r=4294967295+r+1);for(var o=0,i=Math.min(t.length-n,4);o>>8*(e?o:3-o)&255}function qo(t,r,n,e){if(n+e>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function Jo(t,r,n,e,o){return o||qo(t,0,n,4),vo(t,r,n,e,23,4),n+4}function Wo(t,r,n,e,o){return o||qo(t,0,n,8),vo(t,r,n,e,52,8),n+8}mo.prototype.slice=function(t,r){var n,e=this.length;if((t=~~t)<0?(t+=e)<0&&(t=0):e>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeUInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,65535,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeUInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):$o(this,t,r,!0),r+4},mo.prototype.writeUInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeIntLE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=0,u=1,a=0;for(this[r]=255&t;++i>0)-a&255;return r+n},mo.prototype.writeIntBE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=n-1,u=1,a=0;for(this[r+i]=255&t;0<=--i&&(u*=256);)t<0&&0===a&&0!==this[r+i+1]&&(a=1),this[r+i]=(t/u>>0)-a&255;return r+n},mo.prototype.writeInt8=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,1,127,-128),mo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},mo.prototype.writeInt16LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):$o(this,t,r,!0),r+4},mo.prototype.writeInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeFloatLE=function(t,r,n){return Jo(this,t,r,!0,n)},mo.prototype.writeFloatBE=function(t,r,n){return Jo(this,t,r,!1,n)},mo.prototype.writeDoubleLE=function(t,r,n){return Wo(this,t,r,!0,n)},mo.prototype.writeDoubleBE=function(t,r,n){return Wo(this,t,r,!1,n)},mo.prototype.copy=function(t,r,n,e){if(n=n||0,e||0===e||(e=this.length),r>=t.length&&(r=t.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(e<0)throw new RangeError("sourceEnd out of bounds");e>this.length&&(e=this.length),t.length-r>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(t=t||0))for(i=r;i>6|192,63&n|128)}else if(n<65536){if((r-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function Ho(t){return function(t){var r,n,e,o,i;so||ho();var u=t.length;if(0>16&255,i[a++]=e>>8&255,i[a++]=255&e;return 2==o?(e=fo[t.charCodeAt(r)]<<2|fo[t.charCodeAt(r+1)]>>4,i[a++]=255&e):1==o&&(e=fo[t.charCodeAt(r)]<<10|fo[t.charCodeAt(r+1)]<<4|fo[t.charCodeAt(r+2)]>>2,i[a++]=e>>8&255,i[a++]=255&e),i}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(Go,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Ko(t,r,n,e){for(var o=0;o=r.length||o>=t.length);++o)r[o+n]=t[o];return o}function Xo(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}n.setTimeout,n.clearTimeout;var ti=n.performance||{},ri=(ti.now||ti.mozNow||ti.msNow||ti.oNow||ti.webkitNow,function(t){return!Oe(t)});function ni(t,r){var n=Ae(r,function(t,r){return!t[We]});return function(t,r){return $n(t,r)}(n,{})?t:function(t,e){var o={};return e=ne(e),ie(t,function(t,r,n){ut(o,e(t,r,n),t)}),o}(t,function(t,r){return function(t,r){return function(t,e,r){var o;return r(t,function(t,r,n){if(e(t,r,n))return o=r,!1}),o}(t,ne(r),ie)}(n,function(t){return t.alias===r})||r})}function ei(t,r){var n=function(t,r){var n=ni(t,r);return{pristineValues:ye(Ae(r,function(t,r){return uo(n,r)}),function(t){return t.args}),checkAgainstAppProps:Ae(r,function(t,r){return!uo(n,r)}),config:n}}(t,r),e=n.config,o=n.pristineValues;return[function(o,t){return ye(t,function(t,r){var n,e;return ve(o[r])||!0===t[Ve]&&ri(o[r])?be({},t,((n={})[Ge]=!0,n)):((e={})[qe]=o[r],e[Fe]=t[Fe],e[Ve]=t[Ve]||!1,e[$e]=t[$e]||!1,e[Je]=t[Je]||!1,e)})}(e,n.checkAgainstAppProps),o]}var oi=function(t){return Be(t)?t:[t]};var ii=function(t,r){return!Be(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},ui=function(t,r){try{return!!B(r)&&r.apply(null,[t])}catch(t){return!1}};function ai(e){return function(t,r){if(t[Ge])return t[qe];var n=function(t,r){var n,e=[[t[qe]],[(n={},n[Fe]=oi(t[Fe]),n[Ve]=t[Ve],n)]];return Reflect.apply(r,null,e)}(t,e);if(n.length)throw ro("runValidationAction",r,t),new Ke(r,n);if(!1!==t[$e]&&!ii(t[qe],t[$e]))throw ro($e,t[$e]),new He(r);if(!1!==t[Je]&&!ui(t[qe],t[Je]))throw ro(Je,t[Je]),new Xe(r);return t[qe]}}function fi(t,r){var n=t[0],e=t[1],o=ye(n,ai(r));return be(o,e)}function ci(t,r,n,e){return void 0===t&&(t={}),function(t,r){return Promise.resolve(ei(t,r))}(t,r).then(function(t){return fi(t,e)}).then(function(t){return be({},t,n)})}function si(t,r,n,e,o,i){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===i&&(i=!1);var u={};return u.args=t,u.type=r,!0===n&&(u[Me]=!0),Be(e)&&(u[Le]=e),B(o)&&(u[ze]=o),le(i)&&(u[De]=i),u}function hi(e,o,i){return void 0===i&&(i=!1),new Promise(function(t,r){var n=oo(e,o,i);return i?n[xe].length?r(n[xe]):t(n.data):n.length?r(n):t([])})}function li(t,r,n){void 0===n&&(n={});var e=n[Me],o=n[Le],i=n[ze],u=n[De];return si.apply(null,[t,r,e,o,i,u])}var pi,gi,vi=Ye,yi=Se,di=Re,bi=Te,wi=Pe,_i=Be,mi=Oe,Ai=eo,ji=oo,Ei=si,Oi=(pi=oo,function(t,r,n){return void 0===n&&(n={}),ci(t,r,n,pi)}),Pi=(gi=oo,function(t,r,n){return void 0===n&&(n={}),function(t,r,n,e){return void 0===t&&(t={}),be(fi(ei(t,r),e),n)}(t,r,n,gi)});t.JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.6 module: umd",t.checkConfig=Pi,t.checkConfigAsync=Oi,t.constructConfig=Ei,t.createConfig=li,t.isAny=yi,t.isArray=_i,t.isBoolean=bi,t.isNotEmpty=mi,t.isNumber=wi,t.isObject=vi,t.isString=di,t.normalizeArgs=Ai,t.validateAsync=hi,t.validateSync=ji,Object.defineProperty(t,"__esModule",{value:!0})}); //# sourceMappingURL=jsonql-params-validator.umd.js.map diff --git a/packages/validator/dist/jsonql-params-validator.umd.js.map b/packages/validator/dist/jsonql-params-validator.umd.js.map index ce1a9495eea1752ad38ca8f704a5d90dc46dc00b..07b453b652b5939c9781b3bbc36c941a0f70872e 100644 --- a/packages/validator/dist/jsonql-params-validator.umd.js.map +++ b/packages/validator/dist/jsonql-params-validator.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-params-validator.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} \ No newline at end of file +{"version":3,"file":"jsonql-params-validator.umd.js","sources":["../node_modules/buffer-es6/isArray.js"],"sourcesContent":["var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"sn2BAAA"} \ No newline at end of file diff --git a/packages/validator/index.js b/packages/validator/index.js index afc610a6f81ea252009348b7d95eebbc3d84fc67..b398edf1c1669e913d9cdec981f2efe23952aec9 100644 --- a/packages/validator/index.js +++ b/packages/validator/index.js @@ -34,28 +34,3 @@ export const constructConfig = jsonqlOptions.constructConfigFn; export const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync) export const checkConfig = jsonqlOptions.checkConfig(validator.validateSync) - -import isInArray from './src/is-in-array' - -export const inArray = isInArray; - -import checkKeyInObject from './src/check-key-in-object' - -export const isKeyInObject = checkKeyInObject; - -import checkIsContract from './src/check-is-contract' - -export const isContract = checkIsContract; - -// from v1.3.0 -import * as paramsApi from './src/params-api' -// params-api -export const createQuery = paramsApi.createQuery; -export const createQueryStr = paramsApi.createQueryStr; -export const createMutation = paramsApi.createMutation; -export const createMutationStr = paramsApi.createMutationStr; -export const getQueryFromArgs = paramsApi.getQueryFromArgs; -export const getQueryFromPayload = paramsApi.getQueryFromPayload; -export const getMutationFromArgs = paramsApi.getMutationFromArgs; -export const getMutationFromPayload = paramsApi.getMutationFromPayload; -export const getNameFromPayload = paramsApi.getNameFromPayload; diff --git a/packages/validator/package.json b/packages/validator/package.json index 334e72dfc7358efdd52d0ab2d9ae2581a9c37a59..1dd9e70d7f1a6859f0ef5a1da16b5bdc4778be3a 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-params-validator", - "version": "1.4.4", + "version": "1.4.6", "description": "JSONQL parameters validator written in ES6+ to use with the client / server", "module": "index.js", "browser": "dist/jsonql-params-validator.umd.js", @@ -40,6 +40,7 @@ "dependencies": { "jsonql-constants": "^1.7.9", "jsonql-errors": "^1.1.2", + "jsonql-utils": "^0.3.14", "lodash-es": "^4.17.15" }, "devDependencies": { @@ -64,10 +65,6 @@ "server-io-core": "^1.2.0", "superkoa": "^1.0.3" }, - "repository": { - "type": "git", - "url": "git+ssh://git@gitee.com:to1source/jsonql.git" - }, "ava": { "files": [ "tests/*.test.js", @@ -87,6 +84,14 @@ "babelrc": false } }, + "repository": { + "type": "git", + "url": "git+ssh://git@gitee.com:to1source/jsonql.git" + }, + "homepage": "https://jsonql.js.org", + "bugs": { + "url": "https://gitee.com/to1source/jsonql/issues" + }, "engine": { "node": ">=8" }, diff --git a/packages/validator/rollup.config.js b/packages/validator/rollup.config.js index 2ed2ef405a74099d96053b6740ad2f010a2c0568..34e3df322928c4dc5788385daa8cb6be7e401732 100644 --- a/packages/validator/rollup.config.js +++ b/packages/validator/rollup.config.js @@ -29,6 +29,7 @@ let plugins = [ objectAssign: 'Object.assign' }), nodeResolve({ + preferBuiltins: true, mainFields: ['module', 'main', 'browser'] }), commonjs({ @@ -58,7 +59,9 @@ let config = { sourcemap: true, globals: { 'promise-polyfill': 'Promise', - 'debug': 'debug' + 'debug': 'debug', + 'fs': 'fs', + 'util': 'util' } }, external: [ diff --git a/packages/validator/src/check-is-contract.js b/packages/validator/src/check-is-contract.js deleted file mode 100644 index 70c5c3922b635355c8e28753b34bbd9074b40de5..0000000000000000000000000000000000000000 --- a/packages/validator/src/check-is-contract.js +++ /dev/null @@ -1,13 +0,0 @@ -// since this need to use everywhere might as well include in the validator -import { QUERY_NAME, MUTATION_NAME, SOCKET_NAME } from 'jsonql-constants' -import checkKeyInObject from './check-key-in-object' -import { checkIsObject } from './object' - -export default function(contract) { - return checkIsObject(contract) - && ( - checkKeyInObject(contract, QUERY_NAME) - || checkKeyInObject(contract, MUTATION_NAME) - || checkKeyInObject(contract, SOCKET_NAME) - ) -} diff --git a/packages/validator/src/check-key-in-object.js b/packages/validator/src/check-key-in-object.js deleted file mode 100644 index 517b5a4cb38becfbc86cb7f4652c8ebd2d1e04b4..0000000000000000000000000000000000000000 --- a/packages/validator/src/check-key-in-object.js +++ /dev/null @@ -1,13 +0,0 @@ -import isInArray from './is-in-array' - -/** - * @param {object} obj for search - * @param {string} key target - * @return {boolean} true on success - */ -const checkKeyInObject = function(obj, key) { - const keys = Object.keys(obj) - return isInArray(keys, key) -} - -export default checkKeyInObject diff --git a/packages/validator/src/options/check-options-sync.js b/packages/validator/src/options/check-options-sync.js index 9a569092aa514b392a7d43576e6bed4ba59c05e8..7e9efaa365ecf1bb8f5c22b532fb2a1936a41017 100644 --- a/packages/validator/src/options/check-options-sync.js +++ b/packages/validator/src/options/check-options-sync.js @@ -17,5 +17,5 @@ export default function(config = {}, appProps, constProps, cb) { cb ), constProps - ); + ) } diff --git a/packages/validator/src/options/construct-config.js b/packages/validator/src/options/construct-config.js index 5810d8e94c3eadc08508e527ed501275690da57d..6e0fb1f8c88626fa29834f648e843602463d70c8 100644 --- a/packages/validator/src/options/construct-config.js +++ b/packages/validator/src/options/construct-config.js @@ -1,4 +1,5 @@ // create function to construct the config entry so we don't need to keep building object +import { isFunction, isString } from 'lodash-es' import { ARGS_KEY, TYPE_KEY, @@ -6,10 +7,10 @@ import { ENUM_KEY, OPTIONAL_KEY, ALIAS_KEY -} from 'jsonql-constants'; -import { checkIsArray } from '../array'; -import checkIsBoolean from '../boolean'; -import { isFunction, isString } from 'lodash-es'; +} from 'jsonql-constants' + +import { checkIsArray } from '../array' +import checkIsBoolean from '../boolean' // import debug from 'debug'; // const debugFn = debug('jsonql-params-validator:construct-config'); /** @@ -38,4 +39,4 @@ export default function(args, type, optional=false, enumv=false, checker=false, base[ALIAS_KEY] = alias; } return base; -}; +} diff --git a/packages/validator/src/options/prepare-args-for-validation.js b/packages/validator/src/options/prepare-args-for-validation.js index 907eb4a4bc54ccc6047d1f1319160d0311bb3130..389f76d85a482b4cbce8dfeec1ced0c537c9a4f4 100644 --- a/packages/validator/src/options/prepare-args-for-validation.js +++ b/packages/validator/src/options/prepare-args-for-validation.js @@ -7,6 +7,7 @@ import { isEqual, findKey } from 'lodash-es' +import { isKeyInObject } from 'jsonql-utils' import { TYPE_KEY, @@ -17,8 +18,6 @@ import { KEY_WORD, ALIAS_KEY } from '../constants' - -import checkKeyInObject from '../check-key-in-object' import notEmpty from '../not-empty' import { checkIsObject } from '../object' @@ -57,11 +56,11 @@ export function preservePristineValues(config, appProps) { const _config = mapAliasConfigKeys(config, appProps) // take the default value out const pristineValues = mapValues( - omitBy(appProps, (value, key) => checkKeyInObject(_config, key)), + omitBy(appProps, (value, key) => isKeyInObject(_config, key)), value => value.args ) // for testing the value - const checkAgainstAppProps = omitBy(appProps, (value, key) => !checkKeyInObject(_config, key)) + const checkAgainstAppProps = omitBy(appProps, (value, key) => !isKeyInObject(_config, key)) // output return { pristineValues, diff --git a/packages/validator/src/options/run-validation.js b/packages/validator/src/options/run-validation.js index 31e9614203a0ceea31023f58e6123df77ca62545..2709166eb60c3f9059df1c9a5564fb712c996299 100644 --- a/packages/validator/src/options/run-validation.js +++ b/packages/validator/src/options/run-validation.js @@ -1,6 +1,11 @@ // breaking the whole thing up to see what cause the multiple calls issue import { isFunction, merge, mapValues } from 'lodash-es' +import { + JsonqlEnumError, + JsonqlTypeError, + JsonqlCheckerError +} from 'jsonql-errors' import log from '../log' import { TYPE_KEY, @@ -10,11 +15,6 @@ import { CHECKER_KEY, KEY_WORD } from '../constants' -import { - JsonqlEnumError, - JsonqlTypeError, - JsonqlCheckerError -} from 'jsonql-errors' import { checkIsArray } from '../array' // import debug from 'debug'; diff --git a/packages/validator/src/params-api.js b/packages/validator/src/params-api.js deleted file mode 100644 index 64758db4c6bfe91daa9c66ed498c575d01c586c9..0000000000000000000000000000000000000000 --- a/packages/validator/src/params-api.js +++ /dev/null @@ -1,142 +0,0 @@ -// ported from jsonql-params-validator -// craete several helper function to construct / extract the payload -// and make sure they are all the same -import { - PAYLOAD_PARAM_NAME, - CONDITION_PARAM_NAME, - RESOLVER_PARAM_NAME, - QUERY_ARG_NAME -} from 'jsonql-constants' -import { JsonqlValidationError } from 'jsonql-errors' - -import isString from './string' -import { checkIsArray } from './array' -import { checkIsObject } from './object' - -// make sure it's an object -const formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload; - -/** - * Get name from the payload (ported back from jsonql-koa) - * @param {*} payload to extract from - * @return {string} name - */ -export function getNameFromPayload(payload) { - return Object.keys(payload)[0] -} - -/** - * @param {string} resolverName name of function - * @param {array} [args=[]] from the ...args - * @param {boolean} [jsonp = false] add v1.3.0 to koa - * @return {object} formatted argument - */ -export function createQuery(resolverName, args = [], jsonp = false) { - if (isString(resolverName) && checkIsArray(args)) { - let payload = { [QUERY_ARG_NAME]: args } - if (jsonp === true) { - return payload; - } - return { [resolverName]: payload } - } - throw new JsonqlValidationError(`[createQuery] expect resolverName to be string and args to be array!`, { resolverName, args }) -} - -// string version of the above -export function createQueryStr(resolverName, args = [], jsonp = false) { - return JSON.stringify(createQuery(resolverName, args, jsonp)) -} - -/** - * @param {string} resolverName name of function - * @param {*} payload to send - * @param {object} [condition={}] for what - * @param {boolean} [jsonp = false] add v1.3.0 to koa - * @return {object} formatted argument - */ -export function createMutation(resolverName, payload, condition = {}, jsonp = false) { - const _payload = { - [PAYLOAD_PARAM_NAME]: payload, - [CONDITION_PARAM_NAME]: condition - } - if (jsonp === true) { - return _payload; - } - if (isString(resolverName)) { - return { [resolverName]: _payload } - } - throw new JsonqlValidationError(`[createMutation] expect resolverName to be string!`, { resolverName, payload, condition }) -} - -// string version of above -export function createMutationStr(resolverName, payload, condition = {}, jsonp = false) { - return JSON.stringify(createMutation(resolverName, payload, condition, jsonp)) -} - -/** - * Further break down from method below for use else where - * @param {string} resolverName name of fn - * @param {object} payload payload - * @return {object|boolean} false on failed - */ -export function getQueryFromArgs(resolverName, payload) { - if (resolverName && checkIsObject(payload)) { - const args = payload[resolverName]; - if (args[QUERY_ARG_NAME]) { - return { - [RESOLVER_PARAM_NAME]: resolverName, - [QUERY_ARG_NAME]: args[QUERY_ARG_NAME] - } - } - } - return false; -} - -/** - * extra the payload back - * @param {*} payload from http call - * @return {object} resolverName and args - */ -export function getQueryFromPayload(payload) { - const p = formatPayload(payload); - const resolverName = getNameFromPayload(p) - const result = getQueryFromArgs(resolverName, p) - if (result !== false) { - return result; - } - throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload) -} - -/** - * Further break down from method below for use else where - * @param {string} resolverName name of fn - * @param {object} payload payload - * @return {object|boolean} false on failed - */ -export function getMutationFromArgs(resolverName, payload) { - if (resolverName && checkIsObject(payload)) { - const args = payload[resolverName] - if (args) { - return { - [RESOLVER_PARAM_NAME]: resolverName, - [PAYLOAD_PARAM_NAME]: args[PAYLOAD_PARAM_NAME], - [CONDITION_PARAM_NAME]: args[CONDITION_PARAM_NAME] - } - } - } - return false; -} - -/** - * @param {object} payload - * @return {object} resolverName, payload, conditon - */ -export function getMutationFromPayload(payload) { - const p = formatPayload(payload); - const resolverName = getNameFromPayload(p) - const result = getMutationFromArgs(resolverName, p) - if (result !== false) { - return result; - } - throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload) -} diff --git a/packages/validator/src/props-to-interface.js b/packages/validator/src/props-to-interface.js new file mode 100644 index 0000000000000000000000000000000000000000..4d3024d7d3d398cd3aa747bbd1c450c345457b8a --- /dev/null +++ b/packages/validator/src/props-to-interface.js @@ -0,0 +1,10 @@ +/** + * a new method to help work with @type + * take the props (for configurator) then turn them into proper interface + * by default everything will be optional, but you can modify it when done + * @param {object} props the configurator props + * @return {object} the interface style json + */ +export default function propsToInterface(props) { + // @TODO +} diff --git a/packages/validator/tests/construct-config.test.js b/packages/validator/tests/construct-config.test.js index b048fcb69053394fa92ac86e935150afa8989132..b1c90c2db25719e8bae6d94e551daaaf316cc4bc 100644 --- a/packages/validator/tests/construct-config.test.js +++ b/packages/validator/tests/construct-config.test.js @@ -4,8 +4,6 @@ const { checkConfig, constructConfig, createConfig, - isKeyInObject, - isContract, JSONQL_PARAMS_VALIDATOR_INFO } = require('../dist/jsonql-params-validator.umd' /*'../main'*/) const { @@ -23,16 +21,8 @@ const { constProps } = require('./fixtures/export-options') const debug = require('debug')('jsonql-params-validator:test:contruct-config') -// const cjsVersion = require('../dist/jsonql-params-validator.cjs'); -// const umdVersion = require('../dist/jsonql-params-validator.umd'); -test("It should able to check if an object is contract or not", t => { - t.false(isContract('contract')) - t.false(isContract([])) - t.false(isContract({})) - t.true(isContract({query: {getSomething: {}}})) -}) test('It should have a JSONQL_PARAMS_VALIDATOR_INFO', t => { @@ -75,13 +65,3 @@ test('It should able to get the alias and turn into the right prop', t => { t.true( opts[target] === value ) t.falsy( opts[alias] ) }) - -test("Test isKeyInObject is exported or not", t => { - const client = {query: {}, mutation: false, socket: null}; - - t.true(isKeyInObject(client, 'mutation')) - t.true(isKeyInObject(client, 'socket')) - - t.false(isKeyInObject(client, 'auth')) - -}) diff --git a/packages/ws-client/README.md b/packages/ws-client/README.md index fa9299d8cf531c81a09f56272e614e4bd6ba42e7..982f95df9bb8915e8fef8c24cf8d35f2cac68cd2 100644 --- a/packages/ws-client/README.md +++ b/packages/ws-client/README.md @@ -1,18 +1,15 @@ # jsonql-ws-client -This is the client for [jsonql-ws-server](https://www.npmjs.com/package/jsonql-ws-server) -with [socket.io-client](https://github.com/socketio/socket.io-client) and [isomorphic-ws](https://github.com/heineiuo/isomorphic-ws) +> This is the jsonql websocket helper library, not for direct use. -** ONLY THE WebSocket version is working at the moment on node ** +We have break up all the jsonql socket client / server in several modules -# Installation +- @jsonql/ws for WebSocket client / server +- @jsonql/socketio for Socket.io client / server +- @jsonql/primus for Primus clinet / server -```sh -$ npm i jsonql-ws-client -``` -You don't use this module directly. We published it only for management purpose only. -This will be part of the [jsonql-rx-client](https://www.npmjs.com/package/jsonql-rx-client). +Please check [jsonql.js.org](https://jsonql.js.org) for further information --- @@ -20,4 +17,4 @@ MIT [Joel Chu](https://joelchu.com) (c) 2019 -[NEWBRAN LTD](https://newbran.ch) [to1source CN](https://to1source.cn) +Co-develop by [NEWBRAN LTD](https://newbran.ch) and [to1source CN](https://to1source.cn) diff --git a/packages/ws-client/index.js b/packages/ws-client/index.js index 934b4c00d0bd2ae7f727a06d6577234288a5a8b1..ca4dec95d8350e293aaa18e26a96a5dcaeee6696 100644 --- a/packages/ws-client/index.js +++ b/packages/ws-client/index.js @@ -1,5 +1,6 @@ // This is the module entry point import clientGenerator from './src/utils/client-generator' import main from './src/main' - -export default main(clientGenerator) +// as of beta.3 this has been cut down to only the core function +// without the actual socket client / server implementation and +// serve as a support library for the socket implementation for jsonql diff --git a/packages/ws-client/main.js b/packages/ws-client/main.js index d8bb48a42cc857c055844d3dd7bbdc086aadaa08..fbb9234093e5afa791b49fbec8f84fec24fe5cc4 100644 --- a/packages/ws-client/main.js +++ b/packages/ws-client/main.js @@ -1,6 +1,2 @@ -// the node client main interface -const main = require('./src/node/main.cjs') -const clientGenerator = require('./src/node/client-generator') - -// finally export it -module.exports = main(clientGenerator) +require = require("esm")(module/*, options*/) +module.exports = require("./module.js") diff --git a/packages/ws-client/package.json b/packages/ws-client/package.json index 37d20f872f7557aa4e8ac48f61bbf8681336a6ba..23873ae99e1e34b227ae175b6973cc51446313a8 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-beta.2", - "description": "This is the web socket client for jsonql-ws-server", + "version": "1.0.0-beta.3", + "description": "This is the web socket client helper library", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-ws-client.js", @@ -12,24 +12,8 @@ "main.js" ], "scripts": { - "test": "npm run build:cjs && DEBUG=jsonql-ws* ava --verbose", - "test:browser": "DEBUG=jsonql-ws-client*,server-io-core* node ./tests/browser/run-qunit.js", - "test:browser:io": "DEBUG=jsonql-ws-client*,server-io-core* NODE_ENV=io node ./tests/browser/run-qunit.js", - "test:browser:ws:auth": "DEBUG=jsonql-ws-client* NODE_ENV=ws-auth node ./tests/browser/run-qunit.js", - "test:browser:hs": "DEBUG=jsonql-ws-client* node NODE_ENV=hs ./tests/browser/run-qunit.js", - "test:browser:rt": "DEBUG=jsonql-ws-client* node NODE_ENV=rt ./tests/browser/run-qunit.js", - "test:node": "npm run build:test && DEBUG=jsonql-* ava ./tests/test-node.test.js", - "test:chain": "DEBUG=jsonql-ws-client* ava ./tests/io-chain-connection.test.js", - "test:ws": "npm run build:cjs && DEBUG=jsonql-ws-client* ava ./tests/ws-client.test.js", - "test:ws:auth": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava ./tests/ws-client-auth.test.js", - "test:ws:login": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava ./tests/ws-client-auth-login.test.js", - "test:ws:chain": "npm run build:cjs && DEBUG=jsonql-ws-client*,-jsonql-ws-client:nb-event-service ava --verbose ./tests/ws-client-chain.test.js", - "test:io": "npm run build:cjs && DEBUG=jsonql-ws-* ava ./tests/io-client.test.js", - "test:io:hs": "npm run build:cjs && DEBUG=jsonql-*,-jsonql-ws-client:nb-event-service ava ./tests/io-client-hs-auth.test.js", - "test:io:hs:login": "npm run build:cjs && DEBUG=jsonql-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-hs-auth-login.test.js", - "test:io:rt": "npm run build:cjs && DEBUG=jsonql-ws-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-rt-auth.test.js", - "test:io:rt:login": "npm run build:cjs && DEBUG=jsonql-ws-*,-jsonql-ws-client:nb-event-service,socket* ava ./tests/io-client-rt-auth-login.test.js", - "prepare": "npm run build", + "test": "DEBUG=jsonql-ws* ava --verbose", + "_prepare_": "npm run build", "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", @@ -41,38 +25,15 @@ "jsonql", "socket.io", "ws", - "Web Socket" + "Web Socket", + "primus" ], "author": "Joel Chu ", "license": "MIT", "devDependencies": { - "ava": "^2.2.0", - "esm": "^3.2.25", + "ava": "^2.3.0", "fs-extra": "^8.1.0", - "glob": "^7.1.4", - "jsonql-contract": "^1.7.7", - "jsonql-koa": "^1.3.7", - "jsonql-ws-server": "^1.2.0", - "koa": "^2.7.0", - "koa-bodyparser": "^4.2.1", - "rollup": "^1.19.4", - "rollup-plugin-alias": "^1.5.2", - "rollup-plugin-async": "^1.2.0", - "rollup-plugin-buble": "^0.19.8", - "rollup-plugin-bundle-size": "^1.0.3", - "rollup-plugin-commonjs": "^10.0.2", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-json": "^4.0.0", - "rollup-plugin-node-builtins": "^2.1.2", - "rollup-plugin-node-globals": "^1.4.0", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-replace": "^2.2.0", - "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^5.1.1", - "rollup-pluginutils": "^2.8.1", - "server-io-core": "^1.2.0", - "sorcery": "^0.10.0", - "ws": "^7.1.2" + "kefir": "^3.8.6" }, "ava": { "files": [ @@ -95,12 +56,12 @@ "node": ">=8" }, "dependencies": { - "debug": "^4.1.1", - "jsonql-constants": "^1.7.9", - "jsonql-errors": "^1.1.1", - "jsonql-jwt": "^1.2.5", - "jsonql-params-validator": "^1.4.3", - "kefir": "^3.8.6", + "esm": "^3.2.25", + "jsonql-constants": "^1.8.0", + "jsonql-errors": "^1.1.2", + "jsonql-jwt": "^1.3.0", + "jsonql-params-validator": "^1.4.6", + "jsonql-utils": "^0.4.0", "nb-event-service": "^1.8.3" }, "repository": { diff --git a/packages/ws-client/src/create-socket-client.js b/packages/ws-client/src/create-socket-client.js index 084294590a14bc67152fa9a6e937edec7836d21e..60b4df6c9152bae38141c4eb82a22f979da907da 100644 --- a/packages/ws-client/src/create-socket-client.js +++ b/packages/ws-client/src/create-socket-client.js @@ -1,9 +1,11 @@ -import { JsonqlError } from 'jsonql-errors' - +// import { JsonqlError } from 'jsonql-errors' +/* +this have moved out of this package +@TODO need to figure out how to inject them back here import createWsClient from './ws' import createIoClient from './io' - -import { SOCKET_IO, WS, SOCKET_NOT_DEFINE_ERR } from './utils/constants' +*/ +// import { SOCKET_IO, WS, SOCKET_NOT_DEFINE_ERR } from './utils/constants' /** * get the create client instance function @@ -12,6 +14,9 @@ import { SOCKET_IO, WS, SOCKET_NOT_DEFINE_ERR } from './utils/constants' * @public */ export default function createSocketClient(opts, nspMap, ee) { + // idea, instead of serverType we pass the create client method via the opts + return Reflect.apply(opts.createClientMethod, null, [opts, nspMap, ee]) + /* switch (opts.serverType) { case SOCKET_IO: return createIoClient(opts, nspMap, ee) @@ -20,4 +25,5 @@ export default function createSocketClient(opts, nspMap, ee) { default: throw new JsonqlError(SOCKET_NOT_DEFINE_ERR) } + */ } diff --git a/packages/ws-client/src/node/client-generator.js b/packages/ws-client/src/node/client-generator.js index 48edb54b94a5827137a8ed2ab78e775ab1b5866a..788a3153df2b53ac2182f4178dc6bba3c3b87027 100644 --- a/packages/ws-client/src/node/client-generator.js +++ b/packages/ws-client/src/node/client-generator.js @@ -1,6 +1,7 @@ // client generator for node.js // @TODO move this out of the jsonql-jwt +/* const { socketIoNodeHandshakeLogin, socketIoNodeRoundtripLogin, @@ -11,6 +12,7 @@ const { wsNodeClient, wsNodeAuthClient } = require('./ws-client') +*/ const { chainPromises } = require('jsonql-jwt') @@ -20,6 +22,8 @@ const { isString } = require('jsonql-params-validator') const debug = require('debug')('jsonql-ws-client:client-generator:cjs') /** + * @TODO we have taken out all the socket client to their respective package + * now we need to figure out how to inject them back into this client generator * websocket client generator * @param {object} payload with opts, nspMap, ee * @return {object} same just mutate it