From e118f8da095584d72565de82ee42551846da7237 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Sep 2019 17:08:09 +0100 Subject: [PATCH 01/59] ported the params-api over and test passed --- packages/utils/package.json | 5 ++-- packages/utils/src/koa.js | 12 ++++------ packages/utils/src/middleware.js | 23 ++++++++++--------- packages/utils/src/params-api.js | 15 +++++++----- .../tests/params-api.test.js | 2 +- 5 files changed, 29 insertions(+), 28 deletions(-) rename packages/{validator => utils}/tests/params-api.test.js (97%) diff --git a/packages/utils/package.json b/packages/utils/package.json index 81c989e4..f29d945a 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -38,9 +38,10 @@ "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" + "lodash-es": "^4.17.15", + "npm-check-updates": "^3.1.21" }, "devDependencies": { "ava": "^2.3.0" diff --git a/packages/utils/src/koa.js b/packages/utils/src/koa.js index d51d7051..8504b2b4 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -1,11 +1,7 @@ // koa specific methods -import { CONTENT_TYPE } from 'jsonql-constants' +import { CONTENT_TYPE, SUCCESS_STATUS, FORBIDDEN_STATUS } from 'jsonql-constants' import jsonqlErrors from 'jsonql-errors' - - -const SUCCESS_STATE = 200; -const FORBIDDEN_STATE = 403; /** * @TODO need to be more flexible * @param {object} ctx koa @@ -47,7 +43,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 +57,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 +94,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 0aed9d5d..21115e27 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -1,7 +1,7 @@ // this is a collection of middleware methods // should be good to use in Koa or Express -const _ = require('lodash') -const { trim } = _; +// const { trim } = require('lodash-es') + const { QUERY_NAME, MUTATION_NAME, @@ -18,8 +18,9 @@ const { * @param {string} str string * @return {string} dasherize string */ -const dasherize = str => ( - trim(str) +export const dasherize = str => ( + (str+'') + .trim() .replace(/([A-Z])/g, '-$1') .replace(/[-_\s]+/g, '-') .toLowerCase() @@ -30,7 +31,7 @@ const dasherize = str => ( * @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 +40,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 +59,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 +69,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: @@ -86,7 +87,7 @@ const getCallMethod = method => { * @param {object} opts * @return {function} */ -const getPathToFn = function(name, type, opts) { +export const getPathToFn = function(name, type, opts) { const dir = opts.resolverDir; const fileName = dasherize(name); let paths = []; @@ -110,7 +111,7 @@ const getPathToFn = function(name, type, opts) { * @param {mixed} result of fn return * @return {string} stringify data */ -const packResult = result => { +export const packResult = result => { return JSON.stringify({ data: result }) } @@ -121,7 +122,7 @@ 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 } }) diff --git a/packages/utils/src/params-api.js b/packages/utils/src/params-api.js index 64758db4..b3252dfa 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, @@ -114,7 +117,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 { 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 110dde0f..854fb0ac 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' -- Gitee From 03b0ecbe646c0baca06637ee01d058b6d79566d9 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 2 Sep 2019 17:26:12 +0100 Subject: [PATCH 02/59] moving the other non validation related methods out --- packages/utils/index.js | 24 ++- .../src/check-is-contract.js | 0 .../src/check-key-in-object.js | 0 packages/validator/index.js | 25 --- packages/validator/package.json | 14 +- packages/validator/src/params-api.js | 142 ------------------ 6 files changed, 32 insertions(+), 173 deletions(-) rename packages/{validator => utils}/src/check-is-contract.js (100%) rename packages/{validator => utils}/src/check-key-in-object.js (100%) delete mode 100644 packages/validator/src/params-api.js diff --git a/packages/utils/index.js b/packages/utils/index.js index 8e2ff953..a01e4cfe 100644 --- a/packages/utils/index.js +++ b/packages/utils/index.js @@ -2,11 +2,33 @@ // ported from jsonql-params-validator import { chainFns, chainPromises } from './src/chain-fns' +import * as paramsApi from './src/params-api' + + +/* +@TODO +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; +*/ // exports export { // chain-fns chainFns, - chainPromises + chainPromises, + // params-api + createQuery: paramsApi.createQuery, + createQueryStr: paramsApi.createQueryStr, + createMutation: paramsApi.createMutation, + createMutationStr: paramsApi.createMutationStr, + getQueryFromArgs: paramsApi.getQueryFromArgs, + getQueryFromPayload: paramsApi.getQueryFromPayload, + getMutationFromArgs: paramsApi.getMutationFromArgs, + getMutationFromPayload: paramsApi.getMutationFromPayload, + getNameFromPayload: paramsApi.getNameFromPayload } diff --git a/packages/validator/src/check-is-contract.js b/packages/utils/src/check-is-contract.js similarity index 100% rename from packages/validator/src/check-is-contract.js rename to packages/utils/src/check-is-contract.js diff --git a/packages/validator/src/check-key-in-object.js b/packages/utils/src/check-key-in-object.js similarity index 100% rename from packages/validator/src/check-key-in-object.js rename to packages/utils/src/check-key-in-object.js diff --git a/packages/validator/index.js b/packages/validator/index.js index afc610a6..b398edf1 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 334e72df..4522e0ad 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.5", "description": "JSONQL parameters validator written in ES6+ to use with the client / server", "module": "index.js", "browser": "dist/jsonql-params-validator.umd.js", @@ -64,10 +64,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 +83,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/src/params-api.js b/packages/validator/src/params-api.js deleted file mode 100644 index 64758db4..00000000 --- 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) -} -- Gitee From 7ea02ce6f9b17033456686a7f54103150c0cf76c Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 09:50:30 +0100 Subject: [PATCH 03/59] rename the top es export to es.js so when import we can import this directly via jsonql-utils/es --- packages/utils/{index.js => es.js} | 0 packages/utils/main.js | 2 +- packages/utils/package.json | 9 ++++++++- packages/utils/src/check-is-contract.js | 13 ------------- packages/utils/src/check-key-in-object.js | 13 ------------- packages/utils/src/contract.js | 11 +++++++++++ packages/utils/src/error.js | 12 +++--------- packages/utils/src/koa.js | 12 ++++++++++++ packages/utils/src/middleware.js | 4 ++-- 9 files changed, 37 insertions(+), 39 deletions(-) rename packages/utils/{index.js => es.js} (100%) delete mode 100644 packages/utils/src/check-is-contract.js delete mode 100644 packages/utils/src/check-key-in-object.js diff --git a/packages/utils/index.js b/packages/utils/es.js similarity index 100% rename from packages/utils/index.js rename to packages/utils/es.js diff --git a/packages/utils/main.js b/packages/utils/main.js index 188245a2..17d9c0d6 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 f29d945a..257631d9 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", - "module": "index.js", + "module": "es.js", "scripts": { "test": "ava", "test:params": "DEBUG=jsonql* ava ./tests/params-api.test.js" @@ -14,10 +14,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", diff --git a/packages/utils/src/check-is-contract.js b/packages/utils/src/check-is-contract.js deleted file mode 100644 index 70c5c392..00000000 --- a/packages/utils/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/utils/src/check-key-in-object.js b/packages/utils/src/check-key-in-object.js deleted file mode 100644 index 517b5a4c..00000000 --- a/packages/utils/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/utils/src/contract.js b/packages/utils/src/contract.js index da99ce35..4abfac74 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -1,6 +1,17 @@ // contract related methods // This is ported back from ws-server and it will get use in the server / client side +import { QUERY_NAME, MUTATION_NAME, SOCKET_NAME } from 'jsonql-constants' import { isKeyInObject } from './generic' +import { isPlainObject } from 'lodash-es' + +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 diff --git a/packages/utils/src/error.js b/packages/utils/src/error.js index 64e894e8..9679b340 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/koa.js b/packages/utils/src/koa.js index 8504b2b4..e55a4941 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -2,6 +2,18 @@ import { CONTENT_TYPE, SUCCESS_STATUS, FORBIDDEN_STATUS } from 'jsonql-constants' import jsonqlErrors from 'jsonql-errors' +import { + dasherize, + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError +} from './middleware' + + /** * @TODO need to be more flexible * @param {object} ctx koa diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 21115e27..80c7f7ee 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -2,7 +2,7 @@ // should be good to use in Koa or Express // const { trim } = require('lodash-es') -const { +import { QUERY_NAME, MUTATION_NAME, API_REQUEST_METHODS, @@ -10,7 +10,7 @@ const { CONDITION_PARAM_NAME, RESOLVER_PARAM_NAME , QUERY_ARG_NAME -} = require('jsonql-constants') +} from 'jsonql-constants' /** * From underscore.string library -- Gitee From 39bac5870cf16ecead818956317d69b0bfdb537d Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 10:27:12 +0100 Subject: [PATCH 04/59] port the jwt code over but its not currently in use --- packages/utils/src/jwt.js | 28 +++++++++++++++ packages/utils/src/middleware.js | 61 ++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 packages/utils/src/jwt.js diff --git a/packages/utils/src/jwt.js b/packages/utils/src/jwt.js new file mode 100644 index 00000000..c6266292 --- /dev/null +++ b/packages/utils/src/jwt.js @@ -0,0 +1,28 @@ +// 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 + */ +export function buff(str, format = BASE64_FORMAT) { + if (Buffer.isBuffer(str)) { + return str; + } + return new Buffer.from(str, format) +} + +/** + * encode in base64 string + * @param {*} in target + * @return {string} base64 encoded + */ +export const base64Encode = in => window.btoa(unescape(encodeURIComponent(str))) + +/** + * decode from base64 string + * @param {string} in base64 encoded string + * @return {*} decoded payload + */ +export const base64Decode = in => decodeURIComponent(escape(window.atob(str))) diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 80c7f7ee..8d608f8a 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -12,6 +12,8 @@ import { QUERY_ARG_NAME } from 'jsonql-constants' +import { checkKeyInObject } from './generic' + /** * From underscore.string library * @BUG there is a bug here with the non-standard name start with _ @@ -89,10 +91,10 @@ export const getCallMethod = method => { */ 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') ) @@ -127,3 +129,58 @@ export const packError = function(detail, className = 'JsonqlError', statusCode error: { 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 => ( + (checkKeyInObject(result, 'data') && !checkKeyInObject(result, 'error')) ? result.data : result +) + +/** + * 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() }) -- Gitee From 49152afc466272493bc49263043b4521537693b5 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 10:36:37 +0100 Subject: [PATCH 05/59] mapped all the exports and ready to publish for testing --- packages/utils/es.js | 64 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/packages/utils/es.js b/packages/utils/es.js index a01e4cfe..837b82d3 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -1,26 +1,64 @@ // exportfor ES modules // ported from jsonql-params-validator - import { chainFns, chainPromises } from './src/chain-fns' +import { checkIsContract, extractSocketPart, groupByNamespace } from './src/contract' +import { replaceErrors, printError } from './src/error' +import { getDebug, inArray, checkKeyInObject } from './src/generic' +import { + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler +} from './src/koa' +import { + dasherize, + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError +} from './src/middleware' import * as paramsApi from './src/params-api' - -/* -@TODO -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; -*/ - - // exports export { // chain-fns chainFns, chainPromises, + // contract + checkIsContract, + extractSocketPart, + groupByNamespace, + isContract: checkIsContract, // alias + // error + replaceErrors, + printError, + // generic + getDebug, + inArray, + checkKeyInObject, + // koa + isJsonqlPath, + isJsonqlRequest, + isJsonqlConsoleUrl, + handleOutput, + handleHtmlOutput, + ctxErrorHandler, + forbiddenHandler, + // middleware + dasherize, + getDocLen, + headerParser, + isHeaderPresent, + getCallMethod, + getPathToFn, + packResult, + packError, // params-api createQuery: paramsApi.createQuery, createQueryStr: paramsApi.createQueryStr, -- Gitee From 8ebf3a7944f6cc89c97a82ecdda698a9478a4e52 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 10:38:19 +0100 Subject: [PATCH 06/59] update README url and should be ready to publis to 0.1.0 --- packages/utils/README.md | 6 +++--- packages/utils/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utils/README.md b/packages/utils/README.md index 44de9a65..82b58f31 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -1,8 +1,8 @@ -# 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. -Please check [jsonql.org](http://jsonql.org) for more information. +Please check [jsonql](https://jsonql.js.org) for more information. --- diff --git a/packages/utils/package.json b/packages/utils/package.json index 257631d9..825d933e 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "1.0.0", + "version": "0.1.0", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", -- Gitee From 0982ef7c0d4a88f8e448113f79e624aac3318eae Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 10:47:11 +0100 Subject: [PATCH 07/59] just sort out the files export in the npm --- packages/utils/README.md | 2 ++ packages/utils/package.json | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/utils/README.md b/packages/utils/README.md index 82b58f31..34f837ae 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -2,6 +2,8 @@ This is a dependency module for various jsonql node / browser modules. +This is not intend to use directly. + Please check [jsonql](https://jsonql.js.org) for more information. --- diff --git a/packages/utils/package.json b/packages/utils/package.json index 825d933e..fccb0975 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,9 +1,14 @@ { "name": "jsonql-utils", - "version": "0.1.0", + "version": "0.2.0", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", + "files": [ + "main.js", + "es.js", + "src" + ], "scripts": { "test": "ava", "test:params": "DEBUG=jsonql* ava ./tests/params-api.test.js" -- Gitee From 586e8b29fcfd11bda95613dfa8326189e99ffbeb Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 11:02:51 +0100 Subject: [PATCH 08/59] adding the complete list of functions for reference --- packages/utils/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/packages/utils/README.md b/packages/utils/README.md index 34f837ae..08b4a90a 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -6,6 +6,45 @@ This is not intend to use directly. 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 +- checkKeyInObject +- 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 + --- ISC -- Gitee From 6888478b860d7579b8cef873f2ce2525f2e041e2 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 11:05:11 +0100 Subject: [PATCH 09/59] remove the wrong dependecies --- packages/utils/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index fccb0975..95fdfade 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -52,8 +52,7 @@ "esm": "^3.2.25", "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", - "lodash-es": "^4.17.15", - "npm-check-updates": "^3.1.21" + "lodash-es": "^4.17.15" }, "devDependencies": { "ava": "^2.3.0" -- Gitee From 7a495b9704108f29f698324b12b8d02a86167497 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 11:05:59 +0100 Subject: [PATCH 10/59] jsonql-utils to v0.2.1 --- packages/utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index 95fdfade..1ad420bc 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.2.0", + "version": "0.2.1", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", -- Gitee From 955f4294f73d2288ffe993325ff92516f0f7a348 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 13:16:46 +0100 Subject: [PATCH 11/59] porting several more methods over to the jsonql-utils --- packages/jwt/index.js | 8 +- packages/jwt/main.js | 19 +-- packages/jwt/package.json | 2 +- .../jwt/src/client/utils/chain-promises.js | 17 --- .../src/client/utils/group-by-namespace.js | 42 ------ packages/jwt/src/client/utils/helpers.js | 34 ----- packages/jwt/src/client/utils/index.js | 8 - packages/resolver/package.json | 3 +- .../src/client/validate-client-config.js | 3 +- packages/resolver/src/handle-auth-methods.js | 9 +- packages/resolver/src/provide-node-clients.js | 4 +- packages/resolver/src/resolve-methods.js | 38 +---- packages/resolver/src/search-resolvers.js | 43 +----- packages/resolver/src/utils.js | 141 +----------------- packages/utils/es.js | 43 ++++-- packages/utils/src/contract.js | 47 +++++- packages/utils/src/generic.js | 18 +++ 17 files changed, 128 insertions(+), 351 deletions(-) delete mode 100644 packages/jwt/src/client/utils/chain-promises.js delete mode 100644 packages/jwt/src/client/utils/group-by-namespace.js delete mode 100644 packages/jwt/src/client/utils/helpers.js delete mode 100644 packages/jwt/src/client/utils/index.js diff --git a/packages/jwt/index.js b/packages/jwt/index.js index ef8a1efa..ebd322b0 100644 --- a/packages/jwt/index.js +++ b/packages/jwt/index.js @@ -13,7 +13,8 @@ import { wsClient } from './src/client'; -import { groupByNamespace, chainPromises } from './src/client/utils' +// moved to jsonql-utils +// import { groupByNamespace, chainPromises } from './src/client/utils' export { socketIoClient, @@ -26,8 +27,5 @@ export { tokenValidator, wsAuthClient, - wsClient, - - groupByNamespace, - chainPromises + wsClient } diff --git a/packages/jwt/main.js b/packages/jwt/main.js index 355cd9bb..8a747e4d 100644 --- a/packages/jwt/main.js +++ b/packages/jwt/main.js @@ -1,16 +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') +// const { groupByNamespace, chainPromises } = require('./src/helpers/client-utils') // socket.io & ws server side methods const { @@ -51,8 +51,5 @@ module.exports = { tokenValidator, encryptWithPublicPem, - decryptWithPrivatePem, - - groupByNamespace, - chainPromises + decryptWithPrivatePem } diff --git a/packages/jwt/package.json b/packages/jwt/package.json index 02ebc5d5..d5ee0f69 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-jwt", - "version": "1.2.5", + "version": "1.2.6", "description": "jwt authentication helpers library for jsonql", "main": "main.js", "module": "index.js", 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 56dd0128..00000000 --- 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 0c3b340a..00000000 --- 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/helpers.js b/packages/jwt/src/client/utils/helpers.js deleted file mode 100644 index b01efabe..00000000 --- a/packages/jwt/src/client/utils/helpers.js +++ /dev/null @@ -1,34 +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 - */ -function buff(str, format = BASE64_FORMAT) { - if (Buffer.isBuffer(str)) { - return str; - } - return new Buffer.from(str, format) -} - -/** - * encode in base64 string - * @param {*} in target - * @return {string} base64 encoded - */ -const base64Encode = in => window.btoa(unescape(encodeURIComponent(str))) - -/** - * decode from base64 string - * @param {string} in base64 encoded string - * @return {*} decoded payload - */ -const base64Decode = in => decodeURIComponent(escape(window.atob(str))) - - -export { - buff, - base64Encode, - base64Decode -} diff --git a/packages/jwt/src/client/utils/index.js b/packages/jwt/src/client/utils/index.js deleted file mode 100644 index eb5898e6..00000000 --- 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/resolver/package.json b/packages/resolver/package.json index b54ec98e..3019fb5e 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": [ @@ -24,6 +24,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.5", "jsonql-params-validator": "^1.4.4", + "jsonql-utils": "^0.2.1", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/resolver/src/client/validate-client-config.js b/packages/resolver/src/client/validate-client-config.js index bed7e877..07e60cc9 100644 --- a/packages/resolver/src/client/validate-client-config.js +++ b/packages/resolver/src/client/validate-client-config.js @@ -1,5 +1,6 @@ const { join } = require('path') -const { getDebug, inArray } = require('../utils') +const { inArray } = require('jsonql-utils') +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 diff --git a/packages/resolver/src/handle-auth-methods.js b/packages/resolver/src/handle-auth-methods.js index 33e846e5..eeef537b 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 d35f96cd..0faec158 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 381c8c73..10cb99d0 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -9,23 +9,20 @@ const { getErrorNameByInstance, UNKNOWN_ERROR } = require('jsonql-errors') +// @TODO this should move to the jsonql-utils! const { provideUserdata } = require('jsonql-jwt') const { + UNKNOWN_ERROR, 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 +30,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 43cb2787..2f1e5705 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -3,52 +3,13 @@ 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/es.js b/packages/utils/es.js index 837b82d3..c68ab77a 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -1,9 +1,15 @@ // exportfor ES modules // ported from jsonql-params-validator import { chainFns, chainPromises } from './src/chain-fns' -import { checkIsContract, extractSocketPart, groupByNamespace } from './src/contract' +import { + checkIsContract, + extractSocketPart, + groupByNamespace, + findFromContract, + extractArgsFromPayload +} from './src/contract' import { replaceErrors, printError } from './src/error' -import { getDebug, inArray, checkKeyInObject } from './src/generic' +import { getDebug, inArray, checkKeyInObject, injectToFn } from './src/generic' import { isJsonqlPath, isJsonqlRequest, @@ -23,7 +29,17 @@ import { packResult, packError } from './src/middleware' -import * as paramsApi from './src/params-api' +import { + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload +} from './src/params-api' // exports export { @@ -31,6 +47,8 @@ export { chainFns, chainPromises, // contract + findFromContract, + extractArgsFromPayload, checkIsContract, extractSocketPart, groupByNamespace, @@ -42,6 +60,7 @@ export { getDebug, inArray, checkKeyInObject, + injectToFn, // koa isJsonqlPath, isJsonqlRequest, @@ -60,13 +79,13 @@ export { packResult, packError, // params-api - createQuery: paramsApi.createQuery, - createQueryStr: paramsApi.createQueryStr, - createMutation: paramsApi.createMutation, - createMutationStr: paramsApi.createMutationStr, - getQueryFromArgs: paramsApi.getQueryFromArgs, - getQueryFromPayload: paramsApi.getQueryFromPayload, - getMutationFromArgs: paramsApi.getMutationFromArgs, - getMutationFromPayload: paramsApi.getMutationFromPayload, - getNameFromPayload: paramsApi.getNameFromPayload + createQuery, + createQueryStr, + createMutation, + createMutationStr, + getQueryFromArgs, + getQueryFromPayload, + getMutationFromArgs, + getMutationFromPayload, + getNameFromPayload } diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 4abfac74..02ac5a2c 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -1,6 +1,14 @@ // contract related methods // This is ported back from ws-server and it will get use in the server / client side -import { QUERY_NAME, MUTATION_NAME, SOCKET_NAME } from 'jsonql-constants' +import { + QUERY_NAME, + MUTATION_NAME, + SOCKET_NAME + QUERY_ARG_NAME, + PAYLOAD_PARAM_NAME, + CONDITION_PARAM_NAME +} from 'jsonql-constants' +import { JsonqlError } from 'jsonql-errors' import { isKeyInObject } from './generic' import { isPlainObject } from 'lodash-es' @@ -60,3 +68,40 @@ 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 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!`) + } +} diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index bec690ef..6aebc612 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -28,3 +28,21 @@ export const checkKeyInObject = 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 + * @return {function} added property resolver + */ +export function injectToFn(resolver, name, data) { + if (Object.getOwnPropertyDescriptor(resolver, name) === undefined) { + Object.defineProperty(resolver, name, { + value: data, + writable: false // make this immutatble + }) + } + return resolver; +} -- Gitee From 6ae9d00df9dd96de7469b899a9f57ba1ac97cd08 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 17:22:57 +0100 Subject: [PATCH 12/59] adding new methods from jsonql-resolver --- packages/utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index 1ad420bc..9f65cf8b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.2.1", + "version": "0.3.0", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", -- Gitee From 5ecc221f96fa6e810d4602d5095dcf50f26211e9 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 17:26:18 +0100 Subject: [PATCH 13/59] update deps for jsonql-resolvder --- packages/resolver/package.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 3019fb5e..1806279f 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -17,20 +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.2.1", + "jsonql-utils": "^0.3.0", "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": { -- Gitee From 19570bebac22b41a014062434fa39e51b9d8f11c Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 17:30:13 +0100 Subject: [PATCH 14/59] fix a little problem with the mix and match json structure --- packages/utils/es.js | 5 +++-- packages/utils/package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/utils/es.js b/packages/utils/es.js index c68ab77a..a49b0dfa 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -40,7 +40,8 @@ import { getMutationFromPayload, getNameFromPayload } from './src/params-api' - +// alias +const isContract = checkIsContract; // exports export { // chain-fns @@ -52,7 +53,7 @@ export { checkIsContract, extractSocketPart, groupByNamespace, - isContract: checkIsContract, // alias + isContract, // alias // error replaceErrors, printError, diff --git a/packages/utils/package.json b/packages/utils/package.json index 9f65cf8b..ed45328c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.0", + "version": "0.3.1", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", -- Gitee From aa4b424b272f7a7750baec34ae0a404c1c83bdc7 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 17:46:19 +0100 Subject: [PATCH 15/59] apply another fix and remove inline variable with jsonql-constants --- packages/resolver/package.json | 2 +- packages/utils/package.json | 2 +- packages/utils/src/chain-fns.js | 1 - packages/utils/src/contract.js | 9 +++++++-- packages/utils/src/generic.js | 3 +-- packages/utils/src/koa.js | 2 -- packages/utils/src/middleware.js | 30 ++++++++++++++++-------------- 7 files changed, 26 insertions(+), 23 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 1806279f..a44e3917 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.0", + "jsonql-utils": "^0.3.1", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index ed45328c..94395956 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.1", + "version": "0.3.2", "description": "This is not for generate use, it's for jsonql various modules", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/chain-fns.js b/packages/utils/src/chain-fns.js index d9ad6c9b..08b82093 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 02ac5a2c..3bfa7225 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -3,7 +3,7 @@ import { QUERY_NAME, MUTATION_NAME, - SOCKET_NAME + SOCKET_NAME, QUERY_ARG_NAME, PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME @@ -12,6 +12,11 @@ import { JsonqlError } 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) && ( @@ -45,7 +50,7 @@ function extractSocketPart(contract) { export default function groupByNamespace(contract) { let socket = extractSocketPart(contract) if (socket === false) { - throw new Error(`socket not found in contract!`) + throw new JsonqlError(`socket not found in contract!`) } let nspSet = {}; let size = 0; diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 6aebc612..3d248806 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -2,13 +2,12 @@ import debug from 'debug' // import * as _ 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) } /** diff --git a/packages/utils/src/koa.js b/packages/utils/src/koa.js index e55a4941..2e379c0b 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -1,7 +1,6 @@ // koa specific methods import { CONTENT_TYPE, SUCCESS_STATUS, FORBIDDEN_STATUS } from 'jsonql-constants' import jsonqlErrors from 'jsonql-errors' - import { dasherize, getDocLen, @@ -13,7 +12,6 @@ import { packError } from './middleware' - /** * @TODO need to be more flexible * @param {object} ctx koa diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 8d608f8a..4f77de9a 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -1,7 +1,6 @@ // this is a collection of middleware methods // should be good to use in Koa or Express // const { trim } = require('lodash-es') - import { QUERY_NAME, MUTATION_NAME, @@ -9,9 +8,13 @@ import { PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME, RESOLVER_PARAM_NAME , - QUERY_ARG_NAME + QUERY_ARG_NAME, + DATA_KEY, + ERROR_KEY, + INDEX_KEY, + EXT } from 'jsonql-constants' - +const DOT = '.' import { checkKeyInObject } from './generic' /** @@ -84,10 +87,10 @@ export 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 */ export const getPathToFn = function(name, type, opts) { const dir = opts.resolverDir; @@ -96,9 +99,8 @@ export const getPathToFn = function(name, type, opts) { if (opts.contract && opts.contract[type] && opts.contract[type].path) { paths.push(opts.contract[type].path) } - paths.push( join(dir, type, fileName, 'index.js') ) - paths.push( join(dir, type, fileName + '.js') ) - // paths.push( join(dir, fileName + '.js') ); + 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 }) } /** @@ -126,7 +128,7 @@ export const packResult = result => { */ export const packError = function(detail, className = 'JsonqlError', statusCode = 500, message = '') { return JSON.stringify({ - error: { detail, className, statusCode, message } + [ERROR_KEY]: { detail, className, statusCode, message } }) } @@ -138,7 +140,7 @@ export const packError = function(detail, className = 'JsonqlError', statusCode * @return {object} strip the data part out, or if the error is presented */ export const resultHandler = result => ( - (checkKeyInObject(result, 'data') && !checkKeyInObject(result, 'error')) ? result.data : result + (checkKeyInObject(result, DATA_KEY) && !checkKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result ) /** -- Gitee From 2665088b5d2ffc1056b9a78e63be85ff3a5e796e Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 17:53:31 +0100 Subject: [PATCH 16/59] rename the check key in object --- packages/resolver/package.json | 2 +- packages/utils/README.md | 6 ++---- packages/utils/es.js | 4 ++-- packages/utils/package.json | 4 ++-- packages/utils/src/generic.js | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index a44e3917..e869cf32 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.1", + "jsonql-utils": "^0.3.2", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/utils/README.md b/packages/utils/README.md index 08b4a90a..8a59c095 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -1,8 +1,6 @@ # jsonql-utils -This is a dependency module for various jsonql node / browser modules. - -This is not intend to use directly. +> This is a dependency module for various jsonql node / browser modules. Not intend to use directly Please check [jsonql](https://jsonql.js.org) for more information. @@ -18,7 +16,7 @@ Please check [jsonql](https://jsonql.js.org) for more information. - printError - getDebug - inArray -- checkKeyInObject +- isKeyInObject - isJsonqlPath - isJsonqlRequest - isJsonqlConsoleUrl diff --git a/packages/utils/es.js b/packages/utils/es.js index a49b0dfa..0a0360ff 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -9,7 +9,7 @@ import { extractArgsFromPayload } from './src/contract' import { replaceErrors, printError } from './src/error' -import { getDebug, inArray, checkKeyInObject, injectToFn } from './src/generic' +import { getDebug, inArray, isKeyInObject, injectToFn } from './src/generic' import { isJsonqlPath, isJsonqlRequest, @@ -60,7 +60,7 @@ export { // generic getDebug, inArray, - checkKeyInObject, + isKeyInObject, injectToFn, // koa isJsonqlPath, diff --git a/packages/utils/package.json b/packages/utils/package.json index 94395956..4d068263 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "name": "jsonql-utils", - "version": "0.3.2", - "description": "This is not for generate use, it's for jsonql various modules", + "version": "0.3.3", + "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", "files": [ diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 3d248806..3f8cbe57 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -23,7 +23,7 @@ export const inArray = (arr, value) => !!arr.filter(a => a === value).length; * @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) } -- Gitee From e1bb21d94fe52f1e9fca2717796f338013c0f169 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 18:01:38 +0100 Subject: [PATCH 17/59] fix the unexported export --- packages/resolver/package.json | 2 +- packages/utils/package.json | 2 +- packages/utils/src/contract.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index e869cf32..8835ba41 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.2", + "jsonql-utils": "^0.3.3", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index 4d068263..f8144b85 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.3", + "version": "0.3.4", "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 3bfa7225..1e519e96 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -32,7 +32,7 @@ export function checkIsContract(contract) { * @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; } -- Gitee From 9c72f85d8697d9ee61dbaff171a783aa5abc85b2 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 18:04:37 +0100 Subject: [PATCH 18/59] fix the wrong default export --- packages/resolver/package.json | 2 +- packages/utils/package.json | 2 +- packages/utils/src/contract.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 8835ba41..e7105484 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.3", + "jsonql-utils": "^0.3.4", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index f8144b85..be31f957 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.4", + "version": "0.3.5", "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 1e519e96..89de0d92 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -47,7 +47,7 @@ export function extractSocketPart(contract) { * 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) { let socket = extractSocketPart(contract) if (socket === false) { throw new JsonqlError(`socket not found in contract!`) @@ -97,7 +97,7 @@ export function findFromContract(type, name, contract) { * @param {string} type of call * @return {array} args */ -export const extractArgsFromPayload = function(payload, type) { +export function extractArgsFromPayload(payload, type) { switch (type) { case QUERY_NAME: return payload[QUERY_ARG_NAME]; -- Gitee From 283b0768abc7296151df268bfef31dea106f33f0 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 18:12:52 +0100 Subject: [PATCH 19/59] add new test to make sure functions presented before export --- packages/resolver/package.json | 2 +- packages/utils/src/middleware.js | 2 +- packages/utils/tests/fn.test.js | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 packages/utils/tests/fn.test.js diff --git a/packages/resolver/package.json b/packages/resolver/package.json index e7105484..183787df 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.4", + "jsonql-utils": "^0.3.5", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 4f77de9a..83616f00 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -15,7 +15,7 @@ import { EXT } from 'jsonql-constants' const DOT = '.' -import { checkKeyInObject } from './generic' +import { isKeyInObject } from './generic' /** * From underscore.string library diff --git a/packages/utils/tests/fn.test.js b/packages/utils/tests/fn.test.js new file mode 100644 index 00000000..b6a2766f --- /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) +}) -- Gitee From 1741e660f885f90ea514b86e13ca438e5d8cd531 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 19:08:25 +0100 Subject: [PATCH 20/59] add back missing dependency fs to get fn --- packages/resolver/package.json | 2 +- packages/resolver/src/resolve-methods.js | 1 - packages/utils/package.json | 2 +- packages/utils/src/middleware.js | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 183787df..9b989913 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.5", + "jsonql-utils": "^0.3.6", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index 10cb99d0..e487d2cb 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -12,7 +12,6 @@ const { // @TODO this should move to the jsonql-utils! const { provideUserdata } = require('jsonql-jwt') const { - UNKNOWN_ERROR, MODULE_TYPE, DEFAULT_RESOLVER_IMPORT_FILE_NAME } = require('jsonql-constants') diff --git a/packages/utils/package.json b/packages/utils/package.json index be31f957..14d384c0 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.5", + "version": "0.3.7", "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/middleware.js b/packages/utils/src/middleware.js index 83616f00..11ddec7e 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -16,7 +16,7 @@ import { } from 'jsonql-constants' const DOT = '.' import { isKeyInObject } from './generic' - +import fs from 'fs' /** * From underscore.string library * @BUG there is a bug here with the non-standard name start with _ @@ -104,7 +104,7 @@ export const getPathToFn = function(name, type, opts) { const ctn = paths.length; for (let i=0; i Date: Tue, 3 Sep 2019 19:30:47 +0100 Subject: [PATCH 21/59] got to go continue later --- packages/resolver/package.json | 2 +- .../src/client/validate-client-config.js | 5 ++-- packages/resolver/src/search-resolvers.js | 3 +-- packages/utils/es.js | 4 +++- packages/utils/package.json | 2 +- packages/utils/src/contract.js | 24 ++++++++++++++++++- packages/utils/src/middleware.js | 3 ++- packages/utils/src/params-api.js | 21 +++++++++++----- 8 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index 9b989913..ff764c43 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.6", + "jsonql-utils": "^0.3.7", "lodash.merge": "^4.6.2" }, "devDependencies": { diff --git a/packages/resolver/src/client/validate-client-config.js b/packages/resolver/src/client/validate-client-config.js index 07e60cc9..d96067ec 100644 --- a/packages/resolver/src/client/validate-client-config.js +++ b/packages/resolver/src/client/validate-client-config.js @@ -1,5 +1,6 @@ const { join } = require('path') const { inArray } = require('jsonql-utils') +const { JsonqlError } = require('jsonql-errors') const { getDebug } = require('../utils') const debug = getDebug('validate-client-config') /** @@ -17,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/search-resolvers.js b/packages/resolver/src/search-resolvers.js index 2f1e5705..67706a6b 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -1,5 +1,4 @@ // search for the resolver location -const fs = require('fs') const { join } = require('path') const { JsonqlResolverNotFoundError } = require('jsonql-errors') @@ -38,7 +37,7 @@ module.exports = function searchResolvers(name, type, opts, contract) { debug('JsonqlResolverNotFoundError', debugMsg) throw new JsonqlResolverNotFoundError(prod ? 'NOT FOUND!' : debugMsg) } catch(e) { - debug(`throw again?`) + debug(`throw again?`, e.name) throw new JsonqlResolverNotFoundError(e) } } diff --git a/packages/utils/es.js b/packages/utils/es.js index 0a0360ff..5fd74c2c 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -6,7 +6,8 @@ import { extractSocketPart, groupByNamespace, findFromContract, - extractArgsFromPayload + extractArgsFromPayload, + extractParamsFromContract } from './src/contract' import { replaceErrors, printError } from './src/error' import { getDebug, inArray, isKeyInObject, injectToFn } from './src/generic' @@ -50,6 +51,7 @@ export { // contract findFromContract, extractArgsFromPayload, + extractParamsFromContract, checkIsContract, extractSocketPart, groupByNamespace, diff --git a/packages/utils/package.json b/packages/utils/package.json index 14d384c0..dbc2da06 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.7", + "version": "0.3.8", "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/contract.js b/packages/utils/src/contract.js index 89de0d92..ae710e3f 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -1,5 +1,6 @@ // contract related methods // This is ported back from ws-server and it will get use in the server / client side +import fs from 'fs' import { QUERY_NAME, MUTATION_NAME, @@ -8,7 +9,7 @@ import { PAYLOAD_PARAM_NAME, CONDITION_PARAM_NAME } from 'jsonql-constants' -import { JsonqlError } from 'jsonql-errors' +import { JsonqlError, JsonqlResolverNotFoundError } from 'jsonql-errors' import { isKeyInObject } from './generic' import { isPlainObject } from 'lodash-es' @@ -110,3 +111,24 @@ export function extractArgsFromPayload(payload, type) { 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/middleware.js b/packages/utils/src/middleware.js index 11ddec7e..87b99891 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -1,6 +1,7 @@ // this is a collection of middleware methods // should be good to use in Koa or Express // const { trim } = require('lodash-es') +import fs from 'fs' import { QUERY_NAME, MUTATION_NAME, @@ -16,7 +17,7 @@ import { } from 'jsonql-constants' const DOT = '.' import { isKeyInObject } from './generic' -import fs from 'fs' + /** * From underscore.string library * @BUG there is a bug here with the non-standard name start with _ diff --git a/packages/utils/src/params-api.js b/packages/utils/src/params-api.js index b3252dfa..25a4c60f 100644 --- a/packages/utils/src/params-api.js +++ b/packages/utils/src/params-api.js @@ -95,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; } @@ -135,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; } -- Gitee From 88d291ca6193ba8270803b50c0f55cad310c40b1 Mon Sep 17 00:00:00 2001 From: joelchu Date: Tue, 3 Sep 2019 23:16:10 +0100 Subject: [PATCH 22/59] integration with the new jsonql-utils done --- packages/resolver/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/resolver/package.json b/packages/resolver/package.json index ff764c43..627488e3 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -27,7 +27,7 @@ "jsonql-jwt": "^1.2.5", "jsonql-node-client": "^1.1.7", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.7", + "jsonql-utils": "^0.3.8", "lodash.merge": "^4.6.2" }, "devDependencies": { -- Gitee From 72297de8d498f308f1fe86b087fca75b2afb947b Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:06:58 +0100 Subject: [PATCH 23/59] start replacing the internal utils method with the jsonql-utils for jsonql-jwt --- packages/jwt/package.json | 21 +- .../client/socketio/chain-connect-async.js | 2 +- .../jwt/src/client/socketio/chain-connect.js | 2 +- packages/jwt/src/server/socketio/clients.js | 1982 +++++++++++++++++ 4 files changed, 1995 insertions(+), 12 deletions(-) diff --git a/packages/jwt/package.json b/packages/jwt/package.json index d5ee0f69..e719dd44 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-jwt", - "version": "1.2.6", + "version": "1.2.7", "description": "jwt authentication helpers library for jsonql", "main": "main.js", "module": "index.js", @@ -49,13 +49,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.8", "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 +64,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/src/client/socketio/chain-connect-async.js b/packages/jwt/src/client/socketio/chain-connect-async.js index 8bd088d6..c69969e1 100644 --- a/packages/jwt/src/client/socketio/chain-connect-async.js +++ b/packages/jwt/src/client/socketio/chain-connect-async.js @@ -1,6 +1,6 @@ // 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 { socketIoHandshakeLogin, socketIoClientAsync diff --git a/packages/jwt/src/client/socketio/chain-connect.js b/packages/jwt/src/client/socketio/chain-connect.js index c636d6c6..9bc9653f 100644 --- a/packages/jwt/src/client/socketio/chain-connect.js +++ b/packages/jwt/src/client/socketio/chain-connect.js @@ -1,6 +1,6 @@ // 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 { socketIoHandshakeLogin, socketIoClientAsync diff --git a/packages/jwt/src/server/socketio/clients.js b/packages/jwt/src/server/socketio/clients.js index c61013f3..5a90cba8 100644 --- a/packages/jwt/src/server/socketio/clients.js +++ b/packages/jwt/src/server/socketio/clients.js @@ -2,7 +2,11 @@ Object.defineProperty(exports, '__esModule', { value: true }); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + var jsonqlErrors = require('jsonql-errors'); +var jsonqlErrors__default = _interopDefault(jsonqlErrors); +require('debug'); require('jsonql-params-validator'); // this should work on browser as well as node @@ -102,6 +106,1984 @@ function socketIoRoundtripLogin(io, url, token, options) { }) } +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 -- Gitee From dd33002307cca143af90e3debcd3575fa340d771 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:20:41 +0100 Subject: [PATCH 24/59] massive clean up inside the jsonql-jwt --- packages/jwt/package.json | 5 +- packages/jwt/rollup.client-utils.config.js | 78 ------------------- .../client/socketio/chain-connect-async.js | 7 +- .../jwt/src/client/socketio/chain-connect.js | 7 +- packages/jwt/src/crypto/encrypt-decrypt.js | 2 +- packages/jwt/src/crypto/rsa-keys.js | 18 +++-- packages/jwt/src/crypto/rsa-pem-keys.js | 32 ++++---- packages/jwt/src/crypto/sha-key.js | 0 packages/jwt/src/helpers/base64.js | 18 ----- packages/jwt/src/helpers/buff.js | 14 ---- packages/jwt/src/helpers/client-utils.js | 68 ---------------- packages/jwt/src/helpers/index.js | 5 -- packages/jwt/src/jwt/jwt-decode.js | 2 +- packages/jwt/src/jwt/jwt-token.js | 18 +++-- .../src/server/auth/create-token-validator.js | 3 +- 15 files changed, 51 insertions(+), 226 deletions(-) delete mode 100644 packages/jwt/rollup.client-utils.config.js delete mode 100644 packages/jwt/src/crypto/sha-key.js delete mode 100644 packages/jwt/src/helpers/base64.js delete mode 100644 packages/jwt/src/helpers/buff.js delete mode 100644 packages/jwt/src/helpers/client-utils.js delete mode 100644 packages/jwt/src/helpers/index.js diff --git a/packages/jwt/package.json b/packages/jwt/package.json index e719dd44..d9331711 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,7 +1,7 @@ { "name": "jsonql-jwt", "version": "1.2.7", - "description": "jwt authentication helpers library for jsonql", + "description": "jwt authentication helpers library for jsonql browser / node / socket clients", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-jwt.js", @@ -10,9 +10,8 @@ "test:run": "DEBUG=jsonql-jwt* ava", "build": "npm run build:clients && 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:clients": "npm run build:io-client && npm run build:decode", "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", diff --git a/packages/jwt/rollup.client-utils.config.js b/packages/jwt/rollup.client-utils.config.js deleted file mode 100644 index af0ffb69..00000000 --- a/packages/jwt/rollup.client-utils.config.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Rollup config for just building out the decode token to share between cjs and browser - */ -import { join } from 'path' -import buble from 'rollup-plugin-buble' - -// import { terser } from "rollup-plugin-terser" -import replace from 'rollup-plugin-replace' -import commonjs from 'rollup-plugin-commonjs' - -import json from 'rollup-plugin-json' - -import nodeResolve from 'rollup-plugin-node-resolve' -import nodeGlobals from 'rollup-plugin-node-globals' -import builtins from 'rollup-plugin-node-builtins' -import size from 'rollup-plugin-bundle-size' -// support async functions -import async from 'rollup-plugin-async' -// get the version info -import { version } from './package.json' - -const env = process.env.NODE_ENV; - -let plugins = [ - json({ - preferConst: true - }), - buble({ - objectAssign: 'Object.assign' - }), - nodeResolve(), - commonjs({ - include: 'node_modules/**' - }), - nodeGlobals(), - builtins(), - async(), - replace({ - 'process.env.NODE_ENV': JSON.stringify('production'), - '__PLACEHOLDER__': `version: ${version} module: ${env==='prod' ? 'cjs' : 'umd'}` - }), - size() -] - -let config = { - input: join(__dirname, 'src', 'client', 'utils', 'index.js'), - output: { - name: 'jsonqlJwtHelpers', - file: join(__dirname, 'src', 'helpers', 'client-utils.js'), - format: 'cjs', - sourceMap: false, - globals: { - 'jwt-decode': 'jwt_decode', - 'jsonql-params-validator': 'jsonqlParamsValidator', - 'jsonql-errors': 'jsonqlErrors', - 'jsonwebtoken': 'jwt', - 'socket.io-client': 'io', - 'promise-polyfill': 'Promise', - 'debug': 'debug' - } - }, - external: [ - 'jwt-decode', - 'jsonql-params-validator', - 'jsonql-errors', - 'jsonwebtoken', - 'jwt', - 'WebSocket', - 'socket.io-client', - 'io', - 'debug', - 'Promise', - 'promise-polyfill' - ], - plugins: plugins -} - -export default config; diff --git a/packages/jwt/src/client/socketio/chain-connect-async.js b/packages/jwt/src/client/socketio/chain-connect-async.js index c69969e1..fc17ca80 100644 --- a/packages/jwt/src/client/socketio/chain-connect-async.js +++ b/packages/jwt/src/client/socketio/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 '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/jwt/src/client/socketio/chain-connect.js index 9bc9653f..6576e6bd 100644 --- a/packages/jwt/src/client/socketio/chain-connect.js +++ b/packages/jwt/src/client/socketio/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 '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/crypto/encrypt-decrypt.js b/packages/jwt/src/crypto/encrypt-decrypt.js index 2cf607ed..1c4555a3 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 9df050e8..c591a73f 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 a01989b3..0ac647f7 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 e69de29b..00000000 diff --git a/packages/jwt/src/helpers/base64.js b/packages/jwt/src/helpers/base64.js deleted file mode 100644 index bee60163..00000000 --- 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 b711015b..00000000 --- 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 6b16b2c8..00000000 --- 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 3987cb82..00000000 --- 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/jwt-decode.js b/packages/jwt/src/jwt/jwt-decode.js index 32e5c94c..74fadb26 100644 --- a/packages/jwt/src/jwt/jwt-decode.js +++ b/packages/jwt/src/jwt/jwt-decode.js @@ -6,7 +6,7 @@ const buff = require('../helpers/buff') 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 b83e41a9..f276ce4a 100644 --- a/packages/jwt/src/jwt/jwt-token.js +++ b/packages/jwt/src/jwt/jwt-token.js @@ -1,8 +1,15 @@ 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 { tokenValidator } = require('./decode-token') -const debug = require('debug')('jsonql-jwt:jwt-token') + +function buff(str, format = BASE64_FORMAT) { + if (Buffer.isBuffer(str)) { + return str + } + return new Buffer.from(str, format) +} + + /* NOTES about the options: @@ -20,7 +27,7 @@ mutatePayload */ const baseOptions = { algorithm: HSA_ALGO -}; +} /** * Generate a jwt token * @param {object} payload object @@ -30,9 +37,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 e411760b..7f906e4f 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) } } -- Gitee From 18f3bff669d72e008d56567041f276f06f384427 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:30:08 +0100 Subject: [PATCH 25/59] update the injectToFn method with overwrite option to make it more flexible --- packages/utils/package.json | 2 +- packages/utils/src/generic.js | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index dbc2da06..f25707fb 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.8", + "version": "0.3.9", "description": "This is a jsonql dependecy module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 3f8cbe57..5040d5c0 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -34,14 +34,19 @@ export const isKeyInObject = function(obj, key) { * @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) { - if (Object.getOwnPropertyDescriptor(resolver, name) === undefined) { - Object.defineProperty(resolver, name, { - value: data, - writable: false // make this immutatble - }) +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; } -- Gitee From fb3958ff2b470ab64613c5cd1abf15b3b3d84e5e Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:32:31 +0100 Subject: [PATCH 26/59] jsonql-utils to v0.3.9 --- packages/utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index f25707fb..686f381f 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "name": "jsonql-utils", "version": "0.3.9", - "description": "This is a jsonql dependecy module, not for generate use.", + "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", "files": [ -- Gitee From 20fc83e759affa698d22cd08a6b120da26e7c2bc Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:41:58 +0100 Subject: [PATCH 27/59] fix the default is not export by module in the utils and republish again --- packages/jwt/package.json | 2 +- packages/jwt/src/server/socketio/clients.js | 1 + packages/utils/package.json | 2 +- packages/utils/src/koa.js | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/jwt/package.json b/packages/jwt/package.json index d9331711..cdf99d58 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -51,7 +51,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.8", + "jsonql-utils": "^0.3.9", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", diff --git a/packages/jwt/src/server/socketio/clients.js b/packages/jwt/src/server/socketio/clients.js index 5a90cba8..0b00b8c3 100644 --- a/packages/jwt/src/server/socketio/clients.js +++ b/packages/jwt/src/server/socketio/clients.js @@ -2085,6 +2085,7 @@ var performanceNow = 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 diff --git a/packages/utils/package.json b/packages/utils/package.json index 686f381f..ed0bcaed 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.9", + "version": "0.3.10", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/koa.js b/packages/utils/src/koa.js index 2e379c0b..2cf93619 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -1,6 +1,7 @@ // koa specific methods import { CONTENT_TYPE, SUCCESS_STATUS, FORBIDDEN_STATUS } from 'jsonql-constants' -import jsonqlErrors from 'jsonql-errors' +// fix the default is not export by module error +import * as jsonqlErrors from 'jsonql-errors' import { dasherize, getDocLen, -- Gitee From d6966d3106cb5301839ed7b556a71f02b4e73d80 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:45:07 +0100 Subject: [PATCH 28/59] all build successful for jsonql-jwt --- packages/jwt/dist/jsonql-jwt.js | 7602 ++++++++++++++++- packages/jwt/package.json | 2 +- packages/jwt/rollup.config.js | 2 +- packages/jwt/rollup.decode-jwt.config.js | 2 +- .../jwt/rollup.socket-io-client.config.js | 2 +- packages/jwt/src/server/socketio/clients.js | 3 - 6 files changed, 7605 insertions(+), 8 deletions(-) diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index 092067b1..809c28cf 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1 +1,7601 @@ -!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 (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('debug')) : + typeof define === 'function' && define.amd ? define(['exports', 'debug'], factory) : + (global = global || self, factory(global.jsonqlJwt = {}, global.debug)); +}(this, function (exports, debug) { 'use strict'; + + debug = debug && debug.hasOwnProperty('default') ? debug['default'] : debug; + + // 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) + } + + // the core stuff to id if it's calling with jsonql + var DATA_KEY = 'data'; + var ERROR_KEY = 'error'; + var DEFAULT_TYPE = 'any'; + // for contract-cli + var KEY_WORD = 'continue'; + + var TYPE_KEY = 'type'; + var OPTIONAL_KEY = 'optional'; + var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word + var ARGS_KEY = 'args'; + var CHECKER_KEY = 'checker'; + var ALIAS_KEY = 'alias'; + + var OR_SEPERATOR = '|'; + + var STRING_TYPE = 'string'; + var BOOLEAN_TYPE = 'boolean'; + var ARRAY_TYPE = 'array'; + var OBJECT_TYPE = 'object'; + + var NUMBER_TYPE = 'number'; + var ARRAY_TYPE_LFT = 'array.<'; + var ARRAY_TYPE_RGT = '>'; + var NO_STATUS_CODE = -1; + // 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 HSA_ALGO = 'HS256'; + 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); + }); + }) + } + + var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode = function () { + try { + if (!isBrowser() && global$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI() { + if (isBrowser()) { + return 'browser' + } + if (isNode()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + } + + if ( Error ) JsonqlBaseError.__proto__ = Error; + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI() + }; + + return JsonqlBaseError; + }(Error)); + + // this get throw from within the checkOptions when run through the enum failed + var JsonqlEnumError = /*@__PURE__*/(function (Error) { + function JsonqlEnumError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlEnumError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlEnumError); + } + } + + if ( Error ) JsonqlEnumError.__proto__ = Error; + JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); + JsonqlEnumError.prototype.constructor = JsonqlEnumError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlEnumError'; + }; + + Object.defineProperties( JsonqlEnumError, staticAccessors ); + + return JsonqlEnumError; + }(Error)); + + // this will throw from inside the checkOptions + var JsonqlTypeError = /*@__PURE__*/(function (Error) { + function JsonqlTypeError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlTypeError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlTypeError); + } + } + + if ( Error ) JsonqlTypeError.__proto__ = Error; + JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); + JsonqlTypeError.prototype.constructor = JsonqlTypeError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlTypeError'; + }; + + Object.defineProperties( JsonqlTypeError, staticAccessors ); + + return JsonqlTypeError; + }(Error)); + + // allow supply a custom checker function + // if that failed then we throw this error + var JsonqlCheckerError = /*@__PURE__*/(function (Error) { + function JsonqlCheckerError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlCheckerError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlCheckerError); + } + } + + if ( Error ) JsonqlCheckerError.__proto__ = Error; + JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); + JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlCheckerError'; + }; + + Object.defineProperties( JsonqlCheckerError, staticAccessors ); + + return JsonqlCheckerError; + }(Error)); + + // custom validation error class + // when validaton failed + var JsonqlValidationError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlValidationError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlValidationError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlValidationError); + } + } + + if ( JsonqlBaseError ) JsonqlValidationError.__proto__ = JsonqlBaseError; + JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlValidationError.prototype.constructor = JsonqlValidationError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlValidationError'; + }; + + Object.defineProperties( JsonqlValidationError, staticAccessors ); + + return JsonqlValidationError; + }(JsonqlBaseError)); + + /** + * This is a custom error to throw whenever a error happen inside the jsonql + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlError); + } + } + + if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; + JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlError.prototype.constructor = JsonqlError; + + var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlError'; + }; + + staticAccessors.statusCode.get = function () { + return NO_STATUS_CODE; + }; + + Object.defineProperties( JsonqlError, staticAccessors ); + + return JsonqlError; + }(JsonqlBaseError)); + + // 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); + }) + } + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Built-in value references. */ + var Symbol = root.Symbol; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Built-in value references. */ + var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** Used for built-in method references. */ + var funcProto = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype, + objectProto$2 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /* Built-in method references that are verified to be native. */ + var WeakMap = getNative(root, 'WeakMap'); + + /** Built-in value references. */ + var objectCreate = Object.create; + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeNow = Date.now; + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$3.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty$2.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max; + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4; + + return value === proto; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]'; + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$5.hasOwnProperty; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty$3.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag$1 = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** Detect free variable `exports`. */ + var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports$1 && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** Used for built-in method references. */ + var objectProto$6 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$6.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$4.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); + + /** Used for built-in method references. */ + var objectProto$7 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$5 = objectProto$7.hasOwnProperty; + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$5.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$8 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$6 = objectProto$8.hasOwnProperty; + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$6.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /* Built-in method references that are verified to be native. */ + var nativeCreate = getNative(Object, 'create'); + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$9 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$7 = objectProto$9.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$7.call(data, key) ? data[key] : undefined; + } + + /** Used for built-in method references. */ + var objectProto$a = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$8 = objectProto$a.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; + } + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /* Built-in method references that are verified to be native. */ + var Map = getNative(root, 'Map'); + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** Used to match property names within property paths. */ + var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** Used as references for various `Number` constants. */ + var INFINITY$1 = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** Built-in value references. */ + var getPrototype = overArg(Object.getPrototypeOf, Object); + + /** `Object#toString` result references. */ + var objectTag$1 = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto$2 = Function.prototype, + objectProto$b = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$2 = funcProto$2.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$9 = objectProto$b.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString$2.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag$1) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$9.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString$2.call(Ctor) == objectCtorString; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsZWJ = '\\u200d'; + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f', + reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', + rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', + rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, + rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange$1 + ']', + rsCombo = '[' + rsComboRange$1 + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange$1 + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange$1 + ']?', + rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** Detect free variable `exports`. */ + var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; + + /** Built-in value references. */ + var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, + allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** Used for built-in method references. */ + var objectProto$c = Object.prototype; + + /** Built-in value references. */ + var propertyIsEnumerable$1 = objectProto$c.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable$1.call(object, symbol); + }); + }; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols$1 = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'); + + /* Built-in method references that are verified to be native. */ + var Promise$1 = getNative(root, 'Promise'); + + /* Built-in method references that are verified to be native. */ + var Set = getNative(root, 'Set'); + + /** `Object#toString` result references. */ + var mapTag$1 = '[object Map]', + objectTag$2 = '[object Object]', + promiseTag = '[object Promise]', + setTag$1 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; + + var dataViewTag$1 = '[object DataView]'; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise$1), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) || + (Map && getTag(new Map) != mapTag$1) || + (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag$1) || + (WeakMap && getTag(new WeakMap) != weakMapTag$1)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag$2 ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag$1; + case mapCtorString: return mapTag$1; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag$1; + case weakMapCtorString: return weakMapTag$1; + } + } + return result; + }; + } + + var getTag$1 = getTag; + + /** Built-in value references. */ + var Uint8Array$1 = root.Uint8Array; + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED$2); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$1 = 1, + COMPARE_UNORDERED_FLAG$1 = 2; + + /** `Object#toString` result references. */ + var boolTag$1 = '[object Boolean]', + dateTag$1 = '[object Date]', + errorTag$1 = '[object Error]', + mapTag$2 = '[object Map]', + numberTag$1 = '[object Number]', + regexpTag$1 = '[object RegExp]', + setTag$2 = '[object Set]', + stringTag$1 = '[object String]', + symbolTag$1 = '[object Symbol]'; + + var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$2 = '[object DataView]'; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$1 = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag$2: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag$1: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { + return false; + } + return true; + + case boolTag$1: + case dateTag$1: + case numberTag$1: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag$1: + return object.name == other.name && object.message == other.message; + + case regexpTag$1: + case stringTag$1: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag$2: + var convert = mapToArray; + + case setTag$2: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG$1; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag$1: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$2 = 1; + + /** Used for built-in method references. */ + var objectProto$d = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$a = objectProto$d.hasOwnProperty; + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty$a.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$3 = 1; + + /** `Object#toString` result references. */ + var argsTag$2 = '[object Arguments]', + arrayTag$1 = '[object Array]', + objectTag$3 = '[object Object]'; + + /** Used for built-in method references. */ + var objectProto$e = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$b = objectProto$e.hasOwnProperty; + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag$1 : getTag$1(object), + othTag = othIsArr ? arrayTag$1 : getTag$1(other); + + objTag = objTag == argsTag$2 ? objectTag$3 : objTag; + othTag = othTag == argsTag$2 ? objectTag$3 : othTag; + + var objIsObj = objTag == objectTag$3, + othIsObj = othTag == objectTag$3, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { + var objIsWrapped = objIsObj && hasOwnProperty$b.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty$b.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$4 = 1, + COMPARE_UNORDERED_FLAG$2 = 2; + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$5 = 1, + COMPARE_UNORDERED_FLAG$3 = 2; + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); + }; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ + function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate), baseForOwn); + } + + /** `Object#toString` result references. */ + var stringTag$2 = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$2); + } + + /** `Object#toString` result references. */ + var boolTag$2 = '[object Boolean]'; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag$2); + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** `Object#toString` result references. */ + var numberTag$2 = '[object Number]'; + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag$2); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN$1(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** Error message constants. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(baseIteratee(predicate))); + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } + + 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$1 = {}.toString; + + var isArray$1 = Array.isArray || function (arr) { + return toString$1.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$2.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + + function kMaxLength () { + return Buffer$2.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff + } + + function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer$2.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer$2(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$2 (arg, encodingOrOffset, length) { + if (!Buffer$2.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer$2)) { + return new Buffer$2(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$1(this, arg) + } + return from(this, arg, encodingOrOffset, length) + } + + Buffer$2.poolSize = 8192; // not used by this implementation + + // TODO: Legacy, not needed anymore. Remove in next major version. + Buffer$2._augment = function (arr) { + arr.__proto__ = Buffer$2.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$2.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) + }; + + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + Buffer$2.prototype.__proto__ = Uint8Array.prototype; + Buffer$2.__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$2.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) + }; + + function allocUnsafe$1 (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer$2.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$2.allocUnsafe = function (size) { + return allocUnsafe$1(null, size) + }; + /** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ + Buffer$2.allocUnsafeSlow = function (size) { + return allocUnsafe$1(null, size) + }; + + function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer$2.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$2.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer$2.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$1(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$2.isBuffer = isBuffer$1; + function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) + } + + Buffer$2.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$2.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$2.concat = function concat (list, length) { + if (!isArray$1(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer$2.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer$2.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$2.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$2.prototype._isBuffer = true; + + function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; + } + + Buffer$2.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$2.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$2.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$2.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$2.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } + if (this === b) { return true } + return Buffer$2.compare(this, b) === 0 + }; + + Buffer$2.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$2.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$2.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$2.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$2.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 + }; + + Buffer$2.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) + }; + + Buffer$2.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$2.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$2.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$2.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$2.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer$2.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer$2(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$2.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$2.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$2.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + return this[offset] + }; + + Buffer$2.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return this[offset] | (this[offset + 1] << 8) + }; + + Buffer$2.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return (this[offset] << 8) | this[offset + 1] + }; + + Buffer$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, true, 23, 4) + }; + + Buffer$2.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, false, 23, 4) + }; + + Buffer$2.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, true, 52, 8) + }; + + Buffer$2.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$2.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$2.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$2.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } + if (!Buffer$2.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$2.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer$2.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer$2.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$2.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer$2.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$2.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer$2.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$2.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$2.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$2.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } + if (!Buffer$2.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + if (value < 0) { value = 0xff + value + 1; } + this[offset] = (value & 0xff); + return offset + 1 + }; + + Buffer$2.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer$2.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 + }; + + Buffer$2.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) + }; + + Buffer$2.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$2.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) + }; + + Buffer$2.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) + }; + + // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) + Buffer$2.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$2.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$2.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$2.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$2(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$1(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() }; + + /** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ + + function notEmpty (a) { + if (isArray(a)) { + return true; + } + return a !== undefined && a !== null && trim(a) !== ''; + } + + // validator numbers + /** + * @2015-05-04 found a problem if the value is a number like string + * it will pass, so add a check if it's string before we pass to next + * @param {number} value expected value + * @return {boolean} true if OK + */ + var checkIsNumber = function(value) { + return isString(value) ? false : !isNaN$1( parseFloat(value) ) + }; + + // validate string type + /** + * @param {string} value expected value + * @return {boolean} true if OK + */ + var checkIsString = function(value) { + return (trim(value) !== '') ? isString(value) : false; + }; + + // check for boolean + /** + * @param {boolean} value expected + * @return {boolean} true if OK + */ + var checkIsBoolean = function(value) { + return isBoolean(value); + }; + + // validate any thing only check if there is something + /** + * @param {*} value the value + * @param {boolean} [checkNull=true] strict check if there is null value + * @return {boolean} true is OK + */ + var checkIsAny = function(value, checkNull) { + if ( checkNull === void 0 ) checkNull = true; + + if (!isUndefined(value) && value !== '' && trim(value) !== '') { + if (checkNull === false || (checkNull === true && !isNull(value))) { + return true; + } + } + return false; + }; + + // Good practice rule - No magic number + + var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; + var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; + var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; + // @TODO the jsdoc return array. and we should also allow array syntax + var DEFAULT_TYPE$1 = DEFAULT_TYPE; + var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; + var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; + + var TYPE_KEY$1 = TYPE_KEY; + var OPTIONAL_KEY$1 = OPTIONAL_KEY; + var ENUM_KEY$1 = ENUM_KEY; + var ARGS_KEY$1 = ARGS_KEY; + var CHECKER_KEY$1 = CHECKER_KEY; + var ALIAS_KEY$1 = ALIAS_KEY; + + var ARRAY_TYPE$1 = ARRAY_TYPE; + var OBJECT_TYPE$1 = OBJECT_TYPE; + var STRING_TYPE$1 = STRING_TYPE; + var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; + var NUMBER_TYPE$1 = NUMBER_TYPE; + var KEY_WORD$1 = KEY_WORD; + var OR_SEPERATOR$1 = OR_SEPERATOR; + + // not actually in use + // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; + + // primitive types + + /** + * this is a wrapper method to call different one based on their type + * @param {string} type to check + * @return {function} a function to handle the type + */ + var combineFn = function(type) { + switch (type) { + case NUMBER_TYPE$1: + return checkIsNumber; + case STRING_TYPE$1: + return checkIsString; + case BOOLEAN_TYPE$1: + return checkIsBoolean; + default: + return checkIsAny; + } + }; + + // validate array type + + /** + * @param {array} value expected + * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well + * @return {boolean} true if OK + */ + var checkIsArray = function(value, type) { + if ( type === void 0 ) type=''; + + if (isArray(value)) { + if (type === '' || trim(type)==='') { + return true; + } + // we test it in reverse + // @TODO if the type is an array (OR) then what? + // we need to take into account this could be an array + var c = value.filter(function (v) { return !combineFn(type)(v); }); + return !(c.length > 0) + } + return false; + }; + + /** + * check if it matches the array. pattern + * @param {string} type + * @return {boolean|array} false means NO, always return array + */ + var isArrayLike$1 = function(type) { + // @TODO could that have something like array<> instead of array.<>? missing the dot? + // because type script is Array without the dot + if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { + var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); + if (_type.indexOf(OR_SEPERATOR$1)) { + return _type.split(OR_SEPERATOR$1) + } + return [_type] + } + return false; + }; + + /** + * we might encounter something like array. then we need to take it apart + * @param {object} p the prepared object for processing + * @param {string|array} type the type came from + * @return {boolean} for the filter to operate on + */ + var arrayTypeHandler = function(p, type) { + var arg = p.arg; + // need a special case to handle the OR type + // we need to test the args instead of the type(s) + if (type.length > 1) { + return !arg.filter(function (v) { return ( + !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) + ); }).length; + } + // type is array so this will be or! + return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; + }; + + // validate object type + /** + * @TODO if provide with the keys then we need to check if the key:value type as well + * @param {object} value expected + * @param {array} [keys=null] if it has the keys array to compare as well + * @return {boolean} true if OK + */ + var checkIsObject = function(value, keys) { + if ( keys === void 0 ) keys=null; + + if (isPlainObject(value)) { + if (!keys) { + return true; + } + if (checkIsArray(keys)) { + // please note we DON'T care if some is optional + // plese refer to the contract.json for the keys + return !keys.filter(function (key) { + var _value = value[key.name]; + return !(key.type.length > key.type.filter(function (type) { + var tmp; + if (!isUndefined(_value)) { + if ((tmp = isArrayLike$1(type)) !== false) { + return !arrayTypeHandler({arg: _value}, tmp) + // return tmp.filter(t => !checkIsArray(_value, t)).length; + // @TODO there might be an object within an object with keys as well :S + } + return !combineFn(type)(_value) + } + return true; + }).length) + }).length; + } + } + return false; + }; + + /** + * fold this into it's own function to handler different object type + * @param {object} p the prepared object for process + * @return {boolean} + */ + var objectTypeHandler = function(p) { + var arg = p.arg; + var param = p.param; + var _args = [arg]; + if (Array.isArray(param.keys) && param.keys.length) { + _args.push(param.keys); + } + // just simple check + return checkIsObject.apply(null, _args) + }; + + /** + * just a simple util for helping to debug + * @param {array} args arguments + * @return {void} + */ + function log() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.debug) { + Reflect.apply(console.log, console, args); + } + } catch(e) {} + } + + // move the index.js code here that make more sense to find where things are + // import debug from 'debug' + // const debugFn = debug('jsonql-params-validator:validator') + // also export this for use in other places + + /** + * We need to handle those optional parameter without a default value + * @param {object} params from contract.json + * @return {boolean} for filter operation false is actually OK + */ + var optionalHandler = function( params ) { + var arg = params.arg; + var param = params.param; + if (notEmpty(arg)) { + // debug('call optional handler', arg, params); + // loop through the type in param + return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } + ).length) + } + return false; + }; + + /** + * actually picking the validator + * @param {*} type for checking + * @param {*} value for checking + * @return {boolean} true on OK + */ + var validateHandler = function(type, value) { + var tmp; + switch (true) { + case type === OBJECT_TYPE$1: + // debugFn('call OBJECT_TYPE') + return !objectTypeHandler(value) + case type === ARRAY_TYPE$1: + // debugFn('call ARRAY_TYPE') + return !checkIsArray(value.arg) + // @TODO when the type is not present, it always fall through here + // so we need to find a way to actually pre-check the type first + // AKA check the contract.json map before running here + case (tmp = isArrayLike$1(type)) !== false: + // debugFn('call ARRAY_LIKE: %O', value) + return !arrayTypeHandler(value, tmp) + default: + return !combineFn(type)(value.arg) + } + }; + + /** + * it get too longer to fit in one line so break it out from the fn below + * @param {*} arg value + * @param {object} param config + * @return {*} value or apply default value + */ + var getOptionalValue = function(arg, param) { + if (!isUndefined(arg)) { + return arg; + } + return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) + }; + + /** + * padding the arguments with defaultValue if the arguments did not provide the value + * this will be the name export + * @param {array} args normalized arguments + * @param {array} params from contract.json + * @return {array} merge the two together + */ + var normalizeArgs = function(args, params) { + // first we should check if this call require a validation at all + // there will be situation where the function doesn't need args and params + if (!checkIsArray(params)) { + // debugFn('params value', params) + throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) + } + if (params.length === 0) { + return []; + } + if (!checkIsArray(args)) { + throw new JsonqlError(ARGS_NOT_ARRAY_ERR) + } + // debugFn(args, params); + // fall through switch + switch(true) { + case args.length == params.length: // standard + log(1); + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, + param: params[i] + } + ); }) + case params[0].variable === true: // using spread syntax + log(2); + var type = params[0].type; + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, // keep the index for reference + param: params[i] || { type: type, name: '_' } + } + ); }) + // with optional defaultValue parameters + case args.length < params.length: + log(3); + return params.map(function (param, i) { return ( + { + param: param, + index: i, + arg: getOptionalValue(args[i], param), + optional: param.optional || false + } + ); }) + // this one pass more than it should have anything after the args.length will be cast as any type + case args.length > params.length: + log(4); + var ctn = params.length; + // this happens when we have those array. type + var _type = [ DEFAULT_TYPE$1 ]; + // we only looking at the first one, this might be a @BUG + /* + if ((tmp = isArrayLike(params[0].type[0])) !== false) { + _type = tmp; + } */ + // if we use the params as guide then the rest will get throw out + // which is not what we want, instead, anything without the param + // will get a any type and optional flag + return args.map(function (arg, i) { + var optional = i >= ctn ? true : !!params[i].optional; + var param = params[i] || { type: _type, name: ("_" + i) }; + return { + arg: optional ? getOptionalValue(arg, param) : arg, + index: i, + param: param, + optional: optional + } + }) + // @TODO find out if there is more cases not cover + default: // this should never happen + log(5); + // debugFn('args', args) + // debugFn('params', params) + // this is unknown therefore we just throw it! + throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) + } + }; + + // what we want is after the validaton we also get the normalized result + // which is with the optional property if the argument didn't provide it + /** + * process the array of params back to their arguments + * @param {array} result the params result + * @return {array} arguments + */ + var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; + + /** + * validator main interface + * @param {array} args the arguments pass to the method call + * @param {array} params from the contract for that method + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {array} empty array on success, or failed parameter and reasons + */ + var validateSync = function(args, params, withResult) { + var obj; + + if ( withResult === void 0 ) withResult = false; + var cleanArgs = normalizeArgs(args, params); + var checkResult = cleanArgs.filter(function (p) { + // v1.4.4 this fixed the problem, the root level optional is from the last fn + if (p.optional === true || p.param.optional === true) { + return optionalHandler(p) + } + // because array of types means OR so if one pass means pass + return !(p.param.type.length > p.param.type.filter( + function (type) { return validateHandler(type, p); } + ).length) + }); + // using the same convention we been using all this time + return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) + }; + + /** + * @param {array} arr Array for check + * @param {*} value target + * @return {boolean} true on successs + */ + var isInArray = function(arr, value) { + return !!arr.filter(function (a) { return a === value; }).length; + }; + + /** + * @param {object} obj for search + * @param {string} key target + * @return {boolean} true on success + */ + var checkKeyInObject = function(obj, key) { + var keys = Object.keys(obj); + return isInArray(keys, key) + }; + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:prepare') + + // just not to make my head hurt + var isEmpty = function (value) { return !notEmpty(value); }; + + /** + * Map the alias to their key then grab their value over + * @param {object} config the user supplied config + * @param {object} appProps the default option map + * @return {object} the config keys replaced with the appProps key by the ALIAS + */ + function mapAliasConfigKeys(config, appProps) { + // need to do two steps + // 1. take key with alias key + var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); + if (isEqual(aliasMap, {})) { + return config; + } + return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) + } + + /** + * We only want to run the valdiation against the config (user supplied) value + * but keep the defaultOptions untouch + * @param {object} config configuraton supplied by user + * @param {object} appProps the default options map + * @return {object} the pristine values that will add back to the final output + */ + function preservePristineValues(config, appProps) { + // @BUG this will filter out those that is alias key + // we need to first map the alias keys back to their full key + var _config = mapAliasConfigKeys(config, appProps); + // take the default value out + var pristineValues = mapValues( + omitBy(appProps, function (value, key) { return checkKeyInObject(_config, key); }), + function (value) { return value.args; } + ); + // for testing the value + var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !checkKeyInObject(_config, key); }); + // output + return { + pristineValues: pristineValues, + checkAgainstAppProps: checkAgainstAppProps, + config: _config // passing this correct values back + } + } + + /** + * This will take the value that is ONLY need to check + * @param {object} config that one + * @param {object} props map for creating checking + * @return {object} put that arg into the args + */ + function processConfigAction(config, props) { + // debugFn('processConfigAction', props) + // v.1.2.0 add checking if its mark optional and the value is empty then pass + return mapValues(props, function (value, key) { + var obj, obj$1; + + return ( + isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) + ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) + : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) + ); + } + ) + } + + /** + * Quick transform + * @TODO we should only validate those that is pass from the config + * and pass through those values that is from the defaultOptions + * @param {object} opts that one + * @param {object} appProps mutation configuration options + * @return {object} put that arg into the args + */ + function prepareArgsForValidation(opts, appProps) { + var ref = preservePristineValues(opts, appProps); + var config = ref.config; + var pristineValues = ref.pristineValues; + var checkAgainstAppProps = ref.checkAgainstAppProps; + // output + return [ + processConfigAction(config, checkAgainstAppProps), + pristineValues + ] + } + + // breaking the whole thing up to see what cause the multiple calls issue + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:validation') + + /** + * just make sure it returns an array to use + * @param {*} arg input + * @return {array} output + */ + var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; + + /** + * DIY in array + * @param {array} arr to check against + * @param {*} value to check + * @return {boolean} true on OK + */ + var inArray = function (arr, value) { return ( + !!arr.filter(function (v) { return v === value; }).length + ); }; + + /** + * break out to make the code easier to read + * @param {object} value to process + * @param {function} cb the validateSync + * @return {array} empty on success + */ + function validateHandler$1(value, cb) { + var obj; + + // cb is the validateSync methods + var args = [ + [ value[ARGS_KEY$1] ], + [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] + ]; + // debugFn('validateHandler', args) + return Reflect.apply(cb, null, args) + } + + /** + * Check against the enum value if it's provided + * @param {*} value to check + * @param {*} enumv to check against if it's not false + * @return {boolean} true on OK + */ + var enumHandler = function (value, enumv) { + if (checkIsArray(enumv)) { + return inArray(enumv, value) + } + return true; + }; + + /** + * Allow passing a function to check the value + * There might be a problem here if the function is incorrect + * and that will makes it hard to debug what is going on inside + * @TODO there could be a few feature add to this one under different circumstance + * @param {*} value to check + * @param {function} checker for checking + */ + var checkerHandler = function (value, checker) { + try { + return isFunction(checker) ? checker.apply(null, [value]) : false; + } catch (e) { + return false; + } + }; + + /** + * Taken out from the runValidaton this only validate the required values + * @param {array} args from the config2argsAction + * @param {function} cb validateSync + * @return {array} of configuration values + */ + function runValidationAction(cb) { + return function (value, key) { + // debugFn('runValidationAction', key, value) + if (value[KEY_WORD$1]) { + return value[ARGS_KEY$1] + } + var check = validateHandler$1(value, cb); + if (check.length) { + log('runValidationAction', key, value); + throw new JsonqlTypeError(key, check) + } + if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { + log(ENUM_KEY$1, value[ENUM_KEY$1]); + throw new JsonqlEnumError(key) + } + if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { + log(CHECKER_KEY$1, value[CHECKER_KEY$1]); + throw new JsonqlCheckerError(key) + } + return value[ARGS_KEY$1] + } + } + + /** + * @param {object} args from the config2argsAction + * @param {function} cb validateSync + * @return {object} of configuration values + */ + function runValidation(args, cb) { + var argsForValidate = args[0]; + var pristineValues = args[1]; + // turn the thing into an array and see what happen here + // debugFn('_args', argsForValidate) + var result = mapValues(argsForValidate, runValidationAction(cb)); + return merge(result, pristineValues) + } + + // this is port back from the client to share across all projects + + /** + * @param {object} config user provide configuration option + * @param {object} appProps mutation configuration options + * @param {object} constProps the immutable configuration options + * @param {function} cb the validateSync method + * @return {object} Promise resolve merge config object + */ + function checkOptionsSync(config, appProps, constProps, cb) { + if ( config === void 0 ) config = {}; + + return merge( + runValidation( + prepareArgsForValidation(config, appProps), + cb + ), + constProps + ); + } + + // create function to construct the config entry so we don't need to keep building object + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:construct-config'); + /** + * @param {*} args value + * @param {string} type for value + * @param {boolean} [optional=false] + * @param {boolean|array} [enumv=false] + * @param {boolean|function} [checker=false] + * @return {object} config entry + */ + function constructConfigFn(args, type, optional, enumv, checker, alias) { + if ( optional === void 0 ) optional=false; + if ( enumv === void 0 ) enumv=false; + if ( checker === void 0 ) checker=false; + if ( alias === void 0 ) alias=false; + + var base = {}; + base[ARGS_KEY] = args; + base[TYPE_KEY] = type; + if (optional === true) { + base[OPTIONAL_KEY] = true; + } + if (checkIsArray(enumv)) { + base[ENUM_KEY] = enumv; + } + if (isFunction(checker)) { + base[CHECKER_KEY] = checker; + } + if (isString(alias)) { + base[ALIAS_KEY] = alias; + } + return base; + } + + // export also create wrapper methods + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:index'); + + /** + * This has a different interface + * @param {*} value to supply + * @param {string|array} type for checking + * @param {object} params to map against the config check + * @param {array} params.enumv NOT enum + * @param {boolean} params.optional false then nothing + * @param {function} params.checker need more work on this one later + * @param {string} params.alias mostly for cmd + */ + var createConfig = function (value, type, params) { + if ( params === void 0 ) params = {}; + + // Note the enumv not ENUM + // const { enumv, optional, checker, alias } = params; + // let args = [value, type, optional, enumv, checker, alias]; + var o = params[OPTIONAL_KEY]; + var e = params[ENUM_KEY]; + var c = params[CHECKER_KEY]; + var a = params[ALIAS_KEY]; + return constructConfigFn.apply(null, [value, type, o, e, c, a]) + }; + + // copy of above but it's sync + var checkConfig = function(validateSync) { + return function(config, appProps, constantProps) { + if ( constantProps === void 0 ) constantProps = {}; + + return checkOptionsSync(config, appProps, constantProps, validateSync) + } + }; + + // export + // PIA syntax + var isObject$1 = checkIsObject; + var isString$1 = checkIsString; + + var createConfig$1 = createConfig; + var checkConfig$1 = checkConfig(validateSync); + + // 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 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}); + }); + }) + } + + /** + * The code was extracted from: + * https://github.com/davidchambers/Base64.js + */ + + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + + InvalidCharacterError.prototype = new Error(); + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + function polyfill (input) { + var str = String(input).replace(/=+$/, ''); + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + } + + + var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; + + function b64DecodeUnicode(str) { + return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { + var code = p.charCodeAt(0).toString(16).toUpperCase(); + if (code.length < 2) { + code = '0' + code; + } + return '%' + code; + })); + } + + var base64_url_decode = function(str) { + var output = str.replace(/-/g, "+").replace(/_/g, "/"); + switch (output.length % 4) { + case 0: + break; + case 2: + output += "=="; + break; + case 3: + output += "="; + break; + default: + throw "Illegal base64url string!"; + } + + try{ + return b64DecodeUnicode(output); + } catch (err) { + return atob(output); + } + }; + + function InvalidTokenError(message) { + this.message = message; + } + + InvalidTokenError.prototype = new Error(); + InvalidTokenError.prototype.name = 'InvalidTokenError'; + + var lib = function (token,options) { + if (typeof token !== 'string') { + throw new InvalidTokenError('Invalid token specified'); + } + + options = options || {}; + var pos = options.header === true ? 0 : 1; + try { + return JSON.parse(base64_url_decode(token.split('.')[pos])); + } catch (e) { + throw new InvalidTokenError('Invalid token specified: ' + e.message); + } + }; + + var InvalidTokenError_1 = InvalidTokenError; + lib.InvalidTokenError = InvalidTokenError_1; + + // 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); + // we only check the exp for the time being + if (token.exp) { + if (start >= token.exp) { + var expired = new Date(token.exp).toISOString(); + throw new JsonqlError(("Token has expired on " + expired), token) + } + } + return token; + } + + /** + * The browser client version it has far fewer options and it doesn't verify it + * because it couldn't this is the job for the server + * @TODO we need to add some extra proessing here to check for the exp field + * @param {string} token to decrypted + * @return {object} decrypted object + */ + function jwtDecode(token) { + if (isString$1(token)) { + var t = lib(token); + return validate(t) + } + throw new JsonqlError('Token must be a string!') + } + + var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; + + var appProps = { + algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), + expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), + notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), + audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), + subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), + issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), + noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), + header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), + keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), + mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) + }; + + function tokenValidator(config) { + if (!isObject$1(config)) { + return {}; // we just ignore it all together? + } + var result = {}; + var opts = checkConfig$1(config, appProps); + // need to remove options that is false + for (var key in opts) { + if (opts[key]) { + result[key] = opts[key]; + } + } + return result; + } + + // ws client using native WebSocket + + function getWS() { + switch(true) { + case (typeof WebSocket !== 'undefined'): + return WebSocket; + case (typeof MozWebSocket !== 'undefined'): + return MozWebSocket; + // case (typeof global !== 'undefined'): + // return global.WebSocket || global.MozWebSocket; + case (typeof window !== 'undefined'): + return window.WebSocket || window.MozWebSocket; + // case (typeof self !== 'undefined'): + // return self.WebSocket || self.MozWebSocket; + default: + throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!') + } + } + + var WS = getWS(); + /** + * Create a client with auth token + * @param {string} url start with ws:// @TODO check this? + * @param {string} token the jwt token + * @return {object} ws instance + */ + function wsAuthClient(url, token) { + return wsClient((url + "?" + TOKEN_PARAM_NAME + "=" + token)) + } + + /** + * Also create a normal client this is for down stream to able to use in node and browser + * @NOTE CAN NOT pass an option if I do then the brower throw error + * @param {string} url end point + * @return {object} ws instance + */ + function wsClient(url) { + return new WS(url) + } + + exports.decodeToken = jwtDecode; + exports.socketIoChainConnect = socketIoChainConnect; + exports.socketIoClient = socketIoClient; + exports.socketIoClientAsync = socketIoClientAsync; + exports.socketIoHandshakeLogin = socketIoHandshakeLogin; + exports.socketIoRoundtripLogin = socketIoRoundtripLogin; + exports.tokenValidator = tokenValidator; + exports.wsAuthClient = wsAuthClient; + exports.wsClient = wsClient; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); diff --git a/packages/jwt/package.json b/packages/jwt/package.json index cdf99d58..d5178c0f 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -51,7 +51,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.9", + "jsonql-utils": "^0.3.10", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", diff --git a/packages/jwt/rollup.config.js b/packages/jwt/rollup.config.js index e13d498b..3400f01a 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 f2280fe2..e7921eec 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/rollup.socket-io-client.config.js b/packages/jwt/rollup.socket-io-client.config.js index 0c4c5e05..b21b6dfb 100644 --- a/packages/jwt/rollup.socket-io-client.config.js +++ b/packages/jwt/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/server/socketio/clients.js b/packages/jwt/src/server/socketio/clients.js index 0b00b8c3..d6a99a42 100644 --- a/packages/jwt/src/server/socketio/clients.js +++ b/packages/jwt/src/server/socketio/clients.js @@ -2,10 +2,7 @@ Object.defineProperty(exports, '__esModule', { value: true }); -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - var jsonqlErrors = require('jsonql-errors'); -var jsonqlErrors__default = _interopDefault(jsonqlErrors); require('debug'); require('jsonql-params-validator'); -- Gitee From 36203b484614e08d2410afede0a90caef14a77df Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:50:32 +0100 Subject: [PATCH 29/59] update the provide-userdata with the injectToFnm --- packages/jwt/src/server/auth/provide-userdata.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/jwt/src/server/auth/provide-userdata.js b/packages/jwt/src/server/auth/provide-userdata.js index 28ba4a46..981f69ec 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) } -- Gitee From 028b916d52154c81fcab863bf2376667adaa3dbc Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 11:56:49 +0100 Subject: [PATCH 30/59] move the buffer method into the utils --- packages/utils/es.js | 5 ++++- packages/utils/package.json | 2 +- packages/utils/src/node.js | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 packages/utils/src/node.js diff --git a/packages/utils/es.js b/packages/utils/es.js index 5fd74c2c..7c02ef6b 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -41,6 +41,7 @@ import { getMutationFromPayload, getNameFromPayload } from './src/params-api' +import { buff } from './src/node' // alias const isContract = checkIsContract; // exports @@ -90,5 +91,7 @@ export { getQueryFromPayload, getMutationFromArgs, getMutationFromPayload, - getNameFromPayload + getNameFromPayload, + // node + buff } diff --git a/packages/utils/package.json b/packages/utils/package.json index ed0bcaed..0e2c09d0 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.10", + "version": "0.3.11", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/node.js b/packages/utils/src/node.js new file mode 100644 index 00000000..8e5fd990 --- /dev/null +++ b/packages/utils/src/node.js @@ -0,0 +1,15 @@ +// node env methods +import { BASE64_FORMAT } from 'jsonql-constants' + +/** + * create buffer string if it's not + * @param {string} str to create buffer + * @param {string} [format = BASE64_FORMAT] what format to use + * @return {buffer} string + */ +export function buff(str, format = BASE64_FORMAT) { + if (Buffer.isBuffer(str)) { + return str + } + return new Buffer.from(str, format) +} -- Gitee From d68f495536d49670fbdd259db16ab62ecff97366 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 12:00:53 +0100 Subject: [PATCH 31/59] replace the buff method with the jsonql-utils version --- packages/jwt/dist/jsonql-jwt.js | 7602 +--------------------------- packages/jwt/package.json | 2 +- packages/jwt/src/jwt/jwt-decode.js | 8 +- packages/jwt/src/jwt/jwt-token.js | 14 +- 4 files changed, 9 insertions(+), 7617 deletions(-) diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index 809c28cf..b5deca9c 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1,7601 +1 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('debug')) : - typeof define === 'function' && define.amd ? define(['exports', 'debug'], factory) : - (global = global || self, factory(global.jsonqlJwt = {}, global.debug)); -}(this, function (exports, debug) { 'use strict'; - - debug = debug && debug.hasOwnProperty('default') ? debug['default'] : debug; - - // 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) - } - - // the core stuff to id if it's calling with jsonql - var DATA_KEY = 'data'; - var ERROR_KEY = 'error'; - var DEFAULT_TYPE = 'any'; - // for contract-cli - var KEY_WORD = 'continue'; - - var TYPE_KEY = 'type'; - var OPTIONAL_KEY = 'optional'; - var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word - var ARGS_KEY = 'args'; - var CHECKER_KEY = 'checker'; - var ALIAS_KEY = 'alias'; - - var OR_SEPERATOR = '|'; - - var STRING_TYPE = 'string'; - var BOOLEAN_TYPE = 'boolean'; - var ARRAY_TYPE = 'array'; - var OBJECT_TYPE = 'object'; - - var NUMBER_TYPE = 'number'; - var ARRAY_TYPE_LFT = 'array.<'; - var ARRAY_TYPE_RGT = '>'; - var NO_STATUS_CODE = -1; - // 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 HSA_ALGO = 'HS256'; - 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); - }); - }) - } - - var global$1 = (typeof global !== "undefined" ? global : - typeof self !== "undefined" ? self : - typeof window !== "undefined" ? window : {}); - - /** - * some time it's hard to tell where the error is throw from - * because client server throw the same, therefore this util fn - * to add a property to the error object to tell if it's throw - * from client or server - * - */ - - var isBrowser = function () { - try { - if (window || document) { - return true; - } - } catch(e) {} - return false; - }; - - var isNode = function () { - try { - if (!isBrowser() && global$1) { - return true; - } - } catch(e) {} - return false; - }; - - function whereAmI() { - if (isBrowser()) { - return 'browser' - } - if (isNode()) { - return 'node' - } - return 'unknown' - } - - // The base Error of all - - var JsonqlBaseError = /*@__PURE__*/(function (Error) { - function JsonqlBaseError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - } - - if ( Error ) JsonqlBaseError.__proto__ = Error; - JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); - JsonqlBaseError.prototype.constructor = JsonqlBaseError; - - JsonqlBaseError.where = function where () { - return whereAmI() - }; - - return JsonqlBaseError; - }(Error)); - - // this get throw from within the checkOptions when run through the enum failed - var JsonqlEnumError = /*@__PURE__*/(function (Error) { - function JsonqlEnumError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlEnumError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlEnumError); - } - } - - if ( Error ) JsonqlEnumError.__proto__ = Error; - JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); - JsonqlEnumError.prototype.constructor = JsonqlEnumError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlEnumError'; - }; - - Object.defineProperties( JsonqlEnumError, staticAccessors ); - - return JsonqlEnumError; - }(Error)); - - // this will throw from inside the checkOptions - var JsonqlTypeError = /*@__PURE__*/(function (Error) { - function JsonqlTypeError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlTypeError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlTypeError); - } - } - - if ( Error ) JsonqlTypeError.__proto__ = Error; - JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); - JsonqlTypeError.prototype.constructor = JsonqlTypeError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlTypeError'; - }; - - Object.defineProperties( JsonqlTypeError, staticAccessors ); - - return JsonqlTypeError; - }(Error)); - - // allow supply a custom checker function - // if that failed then we throw this error - var JsonqlCheckerError = /*@__PURE__*/(function (Error) { - function JsonqlCheckerError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlCheckerError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlCheckerError); - } - } - - if ( Error ) JsonqlCheckerError.__proto__ = Error; - JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); - JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlCheckerError'; - }; - - Object.defineProperties( JsonqlCheckerError, staticAccessors ); - - return JsonqlCheckerError; - }(Error)); - - // custom validation error class - // when validaton failed - var JsonqlValidationError = /*@__PURE__*/(function (JsonqlBaseError) { - function JsonqlValidationError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - JsonqlBaseError.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlValidationError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlValidationError); - } - } - - if ( JsonqlBaseError ) JsonqlValidationError.__proto__ = JsonqlBaseError; - JsonqlValidationError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); - JsonqlValidationError.prototype.constructor = JsonqlValidationError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlValidationError'; - }; - - Object.defineProperties( JsonqlValidationError, staticAccessors ); - - return JsonqlValidationError; - }(JsonqlBaseError)); - - /** - * This is a custom error to throw whenever a error happen inside the jsonql - * This help us to capture the right error, due to the call happens in sequence - * @param {string} message to tell what happen - * @param {mixed} extra things we want to add, 500? - */ - var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { - function JsonqlError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - JsonqlBaseError.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlError); - } - } - - if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; - JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); - JsonqlError.prototype.constructor = JsonqlError; - - var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlError'; - }; - - staticAccessors.statusCode.get = function () { - return NO_STATUS_CODE; - }; - - Object.defineProperties( JsonqlError, staticAccessors ); - - return JsonqlError; - }(JsonqlBaseError)); - - // 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); - }) - } - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Built-in value references. */ - var Symbol = root.Symbol; - - /** Used for built-in method references. */ - var objectProto = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; - - /** Built-in value references. */ - var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; - } - - /** Used for built-in method references. */ - var objectProto$1 = Object.prototype; - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString$1 = objectProto$1.toString; - - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString$1.call(value); - } - - /** `Object#toString` result references. */ - var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - - /** Built-in value references. */ - var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined; - - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag$1 && symToStringTag$1 in Object(value)) - ? getRawTag(value) - : objectToString(value); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } - - /** `Object#toString` result references. */ - var symbolTag = '[object Symbol]'; - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } - - /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ - function identity(value) { - return value; - } - - /** `Object#toString` result references. */ - var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } - - /** Used to detect overreaching core-js shims. */ - var coreJsData = root['__core-js_shared__']; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** Used for built-in method references. */ - var funcProto = Function.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString = funcProto.toString; - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used for built-in method references. */ - var funcProto$1 = Function.prototype, - objectProto$2 = Object.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString$1 = funcProto$1.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty$1 = objectProto$2.hasOwnProperty; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /* Built-in method references that are verified to be native. */ - var WeakMap = getNative(root, 'WeakMap'); - - /** Built-in value references. */ - var objectCreate = Object.create; - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; - }()); - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 800, - HOT_SPAN = 16; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeNow = Date.now; - - /** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ - function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; - } - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} - }()); - - /** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); - }; - - /** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var setToString = shortOut(baseSetToString); - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); - } - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER = 9007199254740991; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** Used for built-in method references. */ - var objectProto$3 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$2 = objectProto$3.hasOwnProperty; - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty$2.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; - } - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeMax = Math.max; - - /** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ - function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); - } - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER$1 = 9007199254740991; - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; - } - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** Used for built-in method references. */ - var objectProto$4 = Object.prototype; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4; - - return value === proto; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]'; - - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } - - /** Used for built-in method references. */ - var objectProto$5 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$3 = objectProto$5.hasOwnProperty; - - /** Built-in value references. */ - var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty$3.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; - - /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ - function stubFalse() { - return false; - } - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Built-in value references. */ - var Buffer = moduleExports ? root.Buffer : undefined; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** `Object#toString` result references. */ - var argsTag$1 = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag$1 = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** Detect free variable `exports`. */ - var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports$1 && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** Used for built-in method references. */ - var objectProto$6 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$4 = objectProto$6.hasOwnProperty; - - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$4.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; - } - - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeKeys = overArg(Object.keys, Object); - - /** Used for built-in method references. */ - var objectProto$7 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$5 = objectProto$7.hasOwnProperty; - - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty$5.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } - - /** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; - } - - /** Used for built-in method references. */ - var objectProto$8 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$6 = objectProto$8.hasOwnProperty; - - /** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty$6.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); - } - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /* Built-in method references that are verified to be native. */ - var nativeCreate = getNative(Object, 'create'); - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used for built-in method references. */ - var objectProto$9 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$7 = objectProto$9.hasOwnProperty; - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty$7.call(data, key) ? data[key] : undefined; - } - - /** Used for built-in method references. */ - var objectProto$a = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$8 = objectProto$a.hasOwnProperty; - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; - return this; - } - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - this.size = 0; - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** Used for built-in method references. */ - var arrayProto = Array.prototype; - - /** Built-in value references. */ - var splice = arrayProto.splice; - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /* Built-in method references that are verified to be native. */ - var Map = getNative(root, 'Map'); - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; - } - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /** Error message constants. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Expose `MapCache`. - memoize.Cache = MapCache; - - /** Used as the maximum memoize cache size. */ - var MAX_MEMOIZE_SIZE = 500; - - /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ - function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; - } - - /** Used to match property names within property paths. */ - var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); - } - - /** Used as references for various `Number` constants. */ - var INFINITY$1 = 1 / 0; - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** Built-in value references. */ - var getPrototype = overArg(Object.getPrototypeOf, Object); - - /** `Object#toString` result references. */ - var objectTag$1 = '[object Object]'; - - /** Used for built-in method references. */ - var funcProto$2 = Function.prototype, - objectProto$b = Object.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString$2 = funcProto$2.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty$9 = objectProto$b.hasOwnProperty; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString$2.call(Object); - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag$1) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty$9.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString$2.call(Ctor) == objectCtorString; - } - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsZWJ = '\\u200d'; - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } - - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange$1 = '\\ud800-\\udfff', - rsComboMarksRange$1 = '\\u0300-\\u036f', - reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', - rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', - rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, - rsVarRange$1 = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsAstral = '[' + rsAstralRange$1 + ']', - rsCombo = '[' + rsComboRange$1 + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange$1 + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ$1 = '\\u200d'; - - /** Used to compose unicode regexes. */ - var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange$1 + ']?', - rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - this.size = 0; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; - } - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /** Detect free variable `exports`. */ - var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; - - /** Built-in value references. */ - var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, - allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ - function stubArray() { - return []; - } - - /** Used for built-in method references. */ - var objectProto$c = Object.prototype; - - /** Built-in value references. */ - var propertyIsEnumerable$1 = objectProto$c.propertyIsEnumerable; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeGetSymbols = Object.getOwnPropertySymbols; - - /** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable$1.call(object, symbol); - }); - }; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeGetSymbols$1 = Object.getOwnPropertySymbols; - - /** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(root, 'DataView'); - - /* Built-in method references that are verified to be native. */ - var Promise$1 = getNative(root, 'Promise'); - - /* Built-in method references that are verified to be native. */ - var Set = getNative(root, 'Set'); - - /** `Object#toString` result references. */ - var mapTag$1 = '[object Map]', - objectTag$2 = '[object Object]', - promiseTag = '[object Promise]', - setTag$1 = '[object Set]', - weakMapTag$1 = '[object WeakMap]'; - - var dataViewTag$1 = '[object DataView]'; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise$1), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) || - (Map && getTag(new Map) != mapTag$1) || - (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag$1) || - (WeakMap && getTag(new WeakMap) != weakMapTag$1)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag$2 ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag$1; - case mapCtorString: return mapTag$1; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag$1; - case weakMapCtorString: return weakMapTag$1; - } - } - return result; - }; - } - - var getTag$1 = getTag; - - /** Built-in value references. */ - var Uint8Array$1 = root.Uint8Array; - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED$2); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$1 = 1, - COMPARE_UNORDERED_FLAG$1 = 2; - - /** `Object#toString` result references. */ - var boolTag$1 = '[object Boolean]', - dateTag$1 = '[object Date]', - errorTag$1 = '[object Error]', - mapTag$2 = '[object Map]', - numberTag$1 = '[object Number]', - regexpTag$1 = '[object RegExp]', - setTag$2 = '[object Set]', - stringTag$1 = '[object String]', - symbolTag$1 = '[object Symbol]'; - - var arrayBufferTag$1 = '[object ArrayBuffer]', - dataViewTag$2 = '[object DataView]'; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto$1 = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag$2: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag$1: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { - return false; - } - return true; - - case boolTag$1: - case dateTag$1: - case numberTag$1: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag$1: - return object.name == other.name && object.message == other.message; - - case regexpTag$1: - case stringTag$1: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag$2: - var convert = mapToArray; - - case setTag$2: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG$1; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag$1: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$2 = 1; - - /** Used for built-in method references. */ - var objectProto$d = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$a = objectProto$d.hasOwnProperty; - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty$a.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$3 = 1; - - /** `Object#toString` result references. */ - var argsTag$2 = '[object Arguments]', - arrayTag$1 = '[object Array]', - objectTag$3 = '[object Object]'; - - /** Used for built-in method references. */ - var objectProto$e = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$b = objectProto$e.hasOwnProperty; - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag$1 : getTag$1(object), - othTag = othIsArr ? arrayTag$1 : getTag$1(other); - - objTag = objTag == argsTag$2 ? objectTag$3 : objTag; - othTag = othTag == argsTag$2 ? objectTag$3 : othTag; - - var objIsObj = objTag == objectTag$3, - othIsObj = othTag == objectTag$3, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { - var objIsWrapped = objIsObj && hasOwnProperty$b.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty$b.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$4 = 1, - COMPARE_UNORDERED_FLAG$2 = 2; - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$5 = 1, - COMPARE_UNORDERED_FLAG$3 = 2; - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); - }; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ - function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Gets the value at `key`, unless `key` is "__proto__" or "constructor". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function safeGet(object, key) { - if (key === 'constructor' && typeof object[key] === 'function') { - return; - } - - if (key == '__proto__') { - return; - } - - return object[key]; - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || isFunction(objValue)) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - stack || (stack = new Stack); - if (isObject(srcValue)) { - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, baseIteratee(predicate), baseForOwn); - } - - /** `Object#toString` result references. */ - var stringTag$2 = '[object String]'; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$2); - } - - /** `Object#toString` result references. */ - var boolTag$2 = '[object Boolean]'; - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && baseGetTag(value) == boolTag$2); - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** `Object#toString` result references. */ - var numberTag$2 = '[object Number]'; - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && baseGetTag(value) == numberTag$2); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN$1(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = baseIteratee(iteratee); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, iteratee(value, key, object), value); - }); - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = baseIteratee(iteratee); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, key, iteratee(value, key, object)); - }); - return result; - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** Error message constants. */ - var FUNC_ERROR_TEXT$1 = 'Expected a function'; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT$1); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; - - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); - - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } - } - return result; - } - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = baseIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); - } - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(baseIteratee(predicate))); - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g; - - /** - * Removes leading and trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trim(' abc '); - * // => 'abc' - * - * _.trim('-_-abc-_-', '_-'); - * // => 'abc' - * - * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar'] - */ - function trim(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrim, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - chrSymbols = stringToArray(chars), - start = charsStartIndex(strSymbols, chrSymbols), - end = charsEndIndex(strSymbols, chrSymbols) + 1; - - return castSlice(strSymbols, start, end).join(''); - } - - 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$1 = {}.toString; - - var isArray$1 = Array.isArray || function (arr) { - return toString$1.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$2.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined - ? global$1.TYPED_ARRAY_SUPPORT - : true; - - function kMaxLength () { - return Buffer$2.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff - } - - function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length); - that.__proto__ = Buffer$2.prototype; - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer$2(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$2 (arg, encodingOrOffset, length) { - if (!Buffer$2.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer$2)) { - return new Buffer$2(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$1(this, arg) - } - return from(this, arg, encodingOrOffset, length) - } - - Buffer$2.poolSize = 8192; // not used by this implementation - - // TODO: Legacy, not needed anymore. Remove in next major version. - Buffer$2._augment = function (arr) { - arr.__proto__ = Buffer$2.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$2.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) - }; - - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - Buffer$2.prototype.__proto__ = Uint8Array.prototype; - Buffer$2.__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$2.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) - }; - - function allocUnsafe$1 (that, size) { - assertSize(size); - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); - if (!Buffer$2.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$2.allocUnsafe = function (size) { - return allocUnsafe$1(null, size) - }; - /** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ - Buffer$2.allocUnsafeSlow = function (size) { - return allocUnsafe$1(null, size) - }; - - function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8'; - } - - if (!Buffer$2.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$2.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array; - that.__proto__ = Buffer$2.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$1(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$2.isBuffer = isBuffer$1; - function internalIsBuffer (b) { - return !!(b != null && b._isBuffer) - } - - Buffer$2.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$2.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$2.concat = function concat (list, length) { - if (!isArray$1(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer$2.alloc(0) - } - - var i; - if (length === undefined) { - length = 0; - for (i = 0; i < list.length; ++i) { - length += list[i].length; - } - } - - var buffer = Buffer$2.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$2.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$2.prototype._isBuffer = true; - - function swap (b, n, m) { - var i = b[n]; - b[n] = b[m]; - b[m] = i; - } - - Buffer$2.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$2.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$2.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$2.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$2.prototype.equals = function equals (b) { - if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } - if (this === b) { return true } - return Buffer$2.compare(this, b) === 0 - }; - - Buffer$2.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$2.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$2.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$2.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$2.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 - }; - - Buffer$2.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) - }; - - Buffer$2.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$2.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$2.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$2.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$2.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end); - newBuf.__proto__ = Buffer$2.prototype; - } else { - var sliceLen = end - start; - newBuf = new Buffer$2(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$2.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$2.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$2.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 1, this.length); } - return this[offset] - }; - - Buffer$2.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return this[offset] | (this[offset + 1] << 8) - }; - - Buffer$2.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return (this[offset] << 8) | this[offset + 1] - }; - - Buffer$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, true, 23, 4) - }; - - Buffer$2.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, false, 23, 4) - }; - - Buffer$2.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 8, this.length); } - return read(this, offset, true, 52, 8) - }; - - Buffer$2.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$2.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$2.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$2.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } - if (!Buffer$2.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$2.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 - }; - - Buffer$2.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer$2.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$2.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer$2.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$2.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer$2.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$2.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$2.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$2.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } - if (!Buffer$2.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } - if (value < 0) { value = 0xff + value + 1; } - this[offset] = (value & 0xff); - return offset + 1 - }; - - Buffer$2.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 - }; - - Buffer$2.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8); - this[offset + 1] = (value & 0xff); - } else { - objectWriteUInt16(this, value, offset, false); - } - return offset + 2 - }; - - Buffer$2.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } - if (Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) - }; - - Buffer$2.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$2.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) - }; - - Buffer$2.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) - }; - - // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) - Buffer$2.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$2.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$2.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$2.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$2(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$1(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() }; - - /** - * Check several parameter that there is something in the param - * @param {*} param input - * @return {boolean} - */ - - function notEmpty (a) { - if (isArray(a)) { - return true; - } - return a !== undefined && a !== null && trim(a) !== ''; - } - - // validator numbers - /** - * @2015-05-04 found a problem if the value is a number like string - * it will pass, so add a check if it's string before we pass to next - * @param {number} value expected value - * @return {boolean} true if OK - */ - var checkIsNumber = function(value) { - return isString(value) ? false : !isNaN$1( parseFloat(value) ) - }; - - // validate string type - /** - * @param {string} value expected value - * @return {boolean} true if OK - */ - var checkIsString = function(value) { - return (trim(value) !== '') ? isString(value) : false; - }; - - // check for boolean - /** - * @param {boolean} value expected - * @return {boolean} true if OK - */ - var checkIsBoolean = function(value) { - return isBoolean(value); - }; - - // validate any thing only check if there is something - /** - * @param {*} value the value - * @param {boolean} [checkNull=true] strict check if there is null value - * @return {boolean} true is OK - */ - var checkIsAny = function(value, checkNull) { - if ( checkNull === void 0 ) checkNull = true; - - if (!isUndefined(value) && value !== '' && trim(value) !== '') { - if (checkNull === false || (checkNull === true && !isNull(value))) { - return true; - } - } - return false; - }; - - // Good practice rule - No magic number - - var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; - var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; - var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; - // @TODO the jsdoc return array. and we should also allow array syntax - var DEFAULT_TYPE$1 = DEFAULT_TYPE; - var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; - var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; - - var TYPE_KEY$1 = TYPE_KEY; - var OPTIONAL_KEY$1 = OPTIONAL_KEY; - var ENUM_KEY$1 = ENUM_KEY; - var ARGS_KEY$1 = ARGS_KEY; - var CHECKER_KEY$1 = CHECKER_KEY; - var ALIAS_KEY$1 = ALIAS_KEY; - - var ARRAY_TYPE$1 = ARRAY_TYPE; - var OBJECT_TYPE$1 = OBJECT_TYPE; - var STRING_TYPE$1 = STRING_TYPE; - var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; - var NUMBER_TYPE$1 = NUMBER_TYPE; - var KEY_WORD$1 = KEY_WORD; - var OR_SEPERATOR$1 = OR_SEPERATOR; - - // not actually in use - // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; - - // primitive types - - /** - * this is a wrapper method to call different one based on their type - * @param {string} type to check - * @return {function} a function to handle the type - */ - var combineFn = function(type) { - switch (type) { - case NUMBER_TYPE$1: - return checkIsNumber; - case STRING_TYPE$1: - return checkIsString; - case BOOLEAN_TYPE$1: - return checkIsBoolean; - default: - return checkIsAny; - } - }; - - // validate array type - - /** - * @param {array} value expected - * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well - * @return {boolean} true if OK - */ - var checkIsArray = function(value, type) { - if ( type === void 0 ) type=''; - - if (isArray(value)) { - if (type === '' || trim(type)==='') { - return true; - } - // we test it in reverse - // @TODO if the type is an array (OR) then what? - // we need to take into account this could be an array - var c = value.filter(function (v) { return !combineFn(type)(v); }); - return !(c.length > 0) - } - return false; - }; - - /** - * check if it matches the array. pattern - * @param {string} type - * @return {boolean|array} false means NO, always return array - */ - var isArrayLike$1 = function(type) { - // @TODO could that have something like array<> instead of array.<>? missing the dot? - // because type script is Array without the dot - if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { - var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); - if (_type.indexOf(OR_SEPERATOR$1)) { - return _type.split(OR_SEPERATOR$1) - } - return [_type] - } - return false; - }; - - /** - * we might encounter something like array. then we need to take it apart - * @param {object} p the prepared object for processing - * @param {string|array} type the type came from - * @return {boolean} for the filter to operate on - */ - var arrayTypeHandler = function(p, type) { - var arg = p.arg; - // need a special case to handle the OR type - // we need to test the args instead of the type(s) - if (type.length > 1) { - return !arg.filter(function (v) { return ( - !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) - ); }).length; - } - // type is array so this will be or! - return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; - }; - - // validate object type - /** - * @TODO if provide with the keys then we need to check if the key:value type as well - * @param {object} value expected - * @param {array} [keys=null] if it has the keys array to compare as well - * @return {boolean} true if OK - */ - var checkIsObject = function(value, keys) { - if ( keys === void 0 ) keys=null; - - if (isPlainObject(value)) { - if (!keys) { - return true; - } - if (checkIsArray(keys)) { - // please note we DON'T care if some is optional - // plese refer to the contract.json for the keys - return !keys.filter(function (key) { - var _value = value[key.name]; - return !(key.type.length > key.type.filter(function (type) { - var tmp; - if (!isUndefined(_value)) { - if ((tmp = isArrayLike$1(type)) !== false) { - return !arrayTypeHandler({arg: _value}, tmp) - // return tmp.filter(t => !checkIsArray(_value, t)).length; - // @TODO there might be an object within an object with keys as well :S - } - return !combineFn(type)(_value) - } - return true; - }).length) - }).length; - } - } - return false; - }; - - /** - * fold this into it's own function to handler different object type - * @param {object} p the prepared object for process - * @return {boolean} - */ - var objectTypeHandler = function(p) { - var arg = p.arg; - var param = p.param; - var _args = [arg]; - if (Array.isArray(param.keys) && param.keys.length) { - _args.push(param.keys); - } - // just simple check - return checkIsObject.apply(null, _args) - }; - - /** - * just a simple util for helping to debug - * @param {array} args arguments - * @return {void} - */ - function log() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - try { - if (window && window.debug) { - Reflect.apply(console.log, console, args); - } - } catch(e) {} - } - - // move the index.js code here that make more sense to find where things are - // import debug from 'debug' - // const debugFn = debug('jsonql-params-validator:validator') - // also export this for use in other places - - /** - * We need to handle those optional parameter without a default value - * @param {object} params from contract.json - * @return {boolean} for filter operation false is actually OK - */ - var optionalHandler = function( params ) { - var arg = params.arg; - var param = params.param; - if (notEmpty(arg)) { - // debug('call optional handler', arg, params); - // loop through the type in param - return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } - ).length) - } - return false; - }; - - /** - * actually picking the validator - * @param {*} type for checking - * @param {*} value for checking - * @return {boolean} true on OK - */ - var validateHandler = function(type, value) { - var tmp; - switch (true) { - case type === OBJECT_TYPE$1: - // debugFn('call OBJECT_TYPE') - return !objectTypeHandler(value) - case type === ARRAY_TYPE$1: - // debugFn('call ARRAY_TYPE') - return !checkIsArray(value.arg) - // @TODO when the type is not present, it always fall through here - // so we need to find a way to actually pre-check the type first - // AKA check the contract.json map before running here - case (tmp = isArrayLike$1(type)) !== false: - // debugFn('call ARRAY_LIKE: %O', value) - return !arrayTypeHandler(value, tmp) - default: - return !combineFn(type)(value.arg) - } - }; - - /** - * it get too longer to fit in one line so break it out from the fn below - * @param {*} arg value - * @param {object} param config - * @return {*} value or apply default value - */ - var getOptionalValue = function(arg, param) { - if (!isUndefined(arg)) { - return arg; - } - return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) - }; - - /** - * padding the arguments with defaultValue if the arguments did not provide the value - * this will be the name export - * @param {array} args normalized arguments - * @param {array} params from contract.json - * @return {array} merge the two together - */ - var normalizeArgs = function(args, params) { - // first we should check if this call require a validation at all - // there will be situation where the function doesn't need args and params - if (!checkIsArray(params)) { - // debugFn('params value', params) - throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) - } - if (params.length === 0) { - return []; - } - if (!checkIsArray(args)) { - throw new JsonqlError(ARGS_NOT_ARRAY_ERR) - } - // debugFn(args, params); - // fall through switch - switch(true) { - case args.length == params.length: // standard - log(1); - return args.map(function (arg, i) { return ( - { - arg: arg, - index: i, - param: params[i] - } - ); }) - case params[0].variable === true: // using spread syntax - log(2); - var type = params[0].type; - return args.map(function (arg, i) { return ( - { - arg: arg, - index: i, // keep the index for reference - param: params[i] || { type: type, name: '_' } - } - ); }) - // with optional defaultValue parameters - case args.length < params.length: - log(3); - return params.map(function (param, i) { return ( - { - param: param, - index: i, - arg: getOptionalValue(args[i], param), - optional: param.optional || false - } - ); }) - // this one pass more than it should have anything after the args.length will be cast as any type - case args.length > params.length: - log(4); - var ctn = params.length; - // this happens when we have those array. type - var _type = [ DEFAULT_TYPE$1 ]; - // we only looking at the first one, this might be a @BUG - /* - if ((tmp = isArrayLike(params[0].type[0])) !== false) { - _type = tmp; - } */ - // if we use the params as guide then the rest will get throw out - // which is not what we want, instead, anything without the param - // will get a any type and optional flag - return args.map(function (arg, i) { - var optional = i >= ctn ? true : !!params[i].optional; - var param = params[i] || { type: _type, name: ("_" + i) }; - return { - arg: optional ? getOptionalValue(arg, param) : arg, - index: i, - param: param, - optional: optional - } - }) - // @TODO find out if there is more cases not cover - default: // this should never happen - log(5); - // debugFn('args', args) - // debugFn('params', params) - // this is unknown therefore we just throw it! - throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) - } - }; - - // what we want is after the validaton we also get the normalized result - // which is with the optional property if the argument didn't provide it - /** - * process the array of params back to their arguments - * @param {array} result the params result - * @return {array} arguments - */ - var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; - - /** - * validator main interface - * @param {array} args the arguments pass to the method call - * @param {array} params from the contract for that method - * @param {boolean} [withResul=false] if true then this will return the normalize result as well - * @return {array} empty array on success, or failed parameter and reasons - */ - var validateSync = function(args, params, withResult) { - var obj; - - if ( withResult === void 0 ) withResult = false; - var cleanArgs = normalizeArgs(args, params); - var checkResult = cleanArgs.filter(function (p) { - // v1.4.4 this fixed the problem, the root level optional is from the last fn - if (p.optional === true || p.param.optional === true) { - return optionalHandler(p) - } - // because array of types means OR so if one pass means pass - return !(p.param.type.length > p.param.type.filter( - function (type) { return validateHandler(type, p); } - ).length) - }); - // using the same convention we been using all this time - return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) - }; - - /** - * @param {array} arr Array for check - * @param {*} value target - * @return {boolean} true on successs - */ - var isInArray = function(arr, value) { - return !!arr.filter(function (a) { return a === value; }).length; - }; - - /** - * @param {object} obj for search - * @param {string} key target - * @return {boolean} true on success - */ - var checkKeyInObject = function(obj, key) { - var keys = Object.keys(obj); - return isInArray(keys, key) - }; - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:prepare') - - // just not to make my head hurt - var isEmpty = function (value) { return !notEmpty(value); }; - - /** - * Map the alias to their key then grab their value over - * @param {object} config the user supplied config - * @param {object} appProps the default option map - * @return {object} the config keys replaced with the appProps key by the ALIAS - */ - function mapAliasConfigKeys(config, appProps) { - // need to do two steps - // 1. take key with alias key - var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); - if (isEqual(aliasMap, {})) { - return config; - } - return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) - } - - /** - * We only want to run the valdiation against the config (user supplied) value - * but keep the defaultOptions untouch - * @param {object} config configuraton supplied by user - * @param {object} appProps the default options map - * @return {object} the pristine values that will add back to the final output - */ - function preservePristineValues(config, appProps) { - // @BUG this will filter out those that is alias key - // we need to first map the alias keys back to their full key - var _config = mapAliasConfigKeys(config, appProps); - // take the default value out - var pristineValues = mapValues( - omitBy(appProps, function (value, key) { return checkKeyInObject(_config, key); }), - function (value) { return value.args; } - ); - // for testing the value - var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !checkKeyInObject(_config, key); }); - // output - return { - pristineValues: pristineValues, - checkAgainstAppProps: checkAgainstAppProps, - config: _config // passing this correct values back - } - } - - /** - * This will take the value that is ONLY need to check - * @param {object} config that one - * @param {object} props map for creating checking - * @return {object} put that arg into the args - */ - function processConfigAction(config, props) { - // debugFn('processConfigAction', props) - // v.1.2.0 add checking if its mark optional and the value is empty then pass - return mapValues(props, function (value, key) { - var obj, obj$1; - - return ( - isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) - ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) - : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) - ); - } - ) - } - - /** - * Quick transform - * @TODO we should only validate those that is pass from the config - * and pass through those values that is from the defaultOptions - * @param {object} opts that one - * @param {object} appProps mutation configuration options - * @return {object} put that arg into the args - */ - function prepareArgsForValidation(opts, appProps) { - var ref = preservePristineValues(opts, appProps); - var config = ref.config; - var pristineValues = ref.pristineValues; - var checkAgainstAppProps = ref.checkAgainstAppProps; - // output - return [ - processConfigAction(config, checkAgainstAppProps), - pristineValues - ] - } - - // breaking the whole thing up to see what cause the multiple calls issue - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:validation') - - /** - * just make sure it returns an array to use - * @param {*} arg input - * @return {array} output - */ - var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; - - /** - * DIY in array - * @param {array} arr to check against - * @param {*} value to check - * @return {boolean} true on OK - */ - var inArray = function (arr, value) { return ( - !!arr.filter(function (v) { return v === value; }).length - ); }; - - /** - * break out to make the code easier to read - * @param {object} value to process - * @param {function} cb the validateSync - * @return {array} empty on success - */ - function validateHandler$1(value, cb) { - var obj; - - // cb is the validateSync methods - var args = [ - [ value[ARGS_KEY$1] ], - [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] - ]; - // debugFn('validateHandler', args) - return Reflect.apply(cb, null, args) - } - - /** - * Check against the enum value if it's provided - * @param {*} value to check - * @param {*} enumv to check against if it's not false - * @return {boolean} true on OK - */ - var enumHandler = function (value, enumv) { - if (checkIsArray(enumv)) { - return inArray(enumv, value) - } - return true; - }; - - /** - * Allow passing a function to check the value - * There might be a problem here if the function is incorrect - * and that will makes it hard to debug what is going on inside - * @TODO there could be a few feature add to this one under different circumstance - * @param {*} value to check - * @param {function} checker for checking - */ - var checkerHandler = function (value, checker) { - try { - return isFunction(checker) ? checker.apply(null, [value]) : false; - } catch (e) { - return false; - } - }; - - /** - * Taken out from the runValidaton this only validate the required values - * @param {array} args from the config2argsAction - * @param {function} cb validateSync - * @return {array} of configuration values - */ - function runValidationAction(cb) { - return function (value, key) { - // debugFn('runValidationAction', key, value) - if (value[KEY_WORD$1]) { - return value[ARGS_KEY$1] - } - var check = validateHandler$1(value, cb); - if (check.length) { - log('runValidationAction', key, value); - throw new JsonqlTypeError(key, check) - } - if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { - log(ENUM_KEY$1, value[ENUM_KEY$1]); - throw new JsonqlEnumError(key) - } - if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { - log(CHECKER_KEY$1, value[CHECKER_KEY$1]); - throw new JsonqlCheckerError(key) - } - return value[ARGS_KEY$1] - } - } - - /** - * @param {object} args from the config2argsAction - * @param {function} cb validateSync - * @return {object} of configuration values - */ - function runValidation(args, cb) { - var argsForValidate = args[0]; - var pristineValues = args[1]; - // turn the thing into an array and see what happen here - // debugFn('_args', argsForValidate) - var result = mapValues(argsForValidate, runValidationAction(cb)); - return merge(result, pristineValues) - } - - // this is port back from the client to share across all projects - - /** - * @param {object} config user provide configuration option - * @param {object} appProps mutation configuration options - * @param {object} constProps the immutable configuration options - * @param {function} cb the validateSync method - * @return {object} Promise resolve merge config object - */ - function checkOptionsSync(config, appProps, constProps, cb) { - if ( config === void 0 ) config = {}; - - return merge( - runValidation( - prepareArgsForValidation(config, appProps), - cb - ), - constProps - ); - } - - // create function to construct the config entry so we don't need to keep building object - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:construct-config'); - /** - * @param {*} args value - * @param {string} type for value - * @param {boolean} [optional=false] - * @param {boolean|array} [enumv=false] - * @param {boolean|function} [checker=false] - * @return {object} config entry - */ - function constructConfigFn(args, type, optional, enumv, checker, alias) { - if ( optional === void 0 ) optional=false; - if ( enumv === void 0 ) enumv=false; - if ( checker === void 0 ) checker=false; - if ( alias === void 0 ) alias=false; - - var base = {}; - base[ARGS_KEY] = args; - base[TYPE_KEY] = type; - if (optional === true) { - base[OPTIONAL_KEY] = true; - } - if (checkIsArray(enumv)) { - base[ENUM_KEY] = enumv; - } - if (isFunction(checker)) { - base[CHECKER_KEY] = checker; - } - if (isString(alias)) { - base[ALIAS_KEY] = alias; - } - return base; - } - - // export also create wrapper methods - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:index'); - - /** - * This has a different interface - * @param {*} value to supply - * @param {string|array} type for checking - * @param {object} params to map against the config check - * @param {array} params.enumv NOT enum - * @param {boolean} params.optional false then nothing - * @param {function} params.checker need more work on this one later - * @param {string} params.alias mostly for cmd - */ - var createConfig = function (value, type, params) { - if ( params === void 0 ) params = {}; - - // Note the enumv not ENUM - // const { enumv, optional, checker, alias } = params; - // let args = [value, type, optional, enumv, checker, alias]; - var o = params[OPTIONAL_KEY]; - var e = params[ENUM_KEY]; - var c = params[CHECKER_KEY]; - var a = params[ALIAS_KEY]; - return constructConfigFn.apply(null, [value, type, o, e, c, a]) - }; - - // copy of above but it's sync - var checkConfig = function(validateSync) { - return function(config, appProps, constantProps) { - if ( constantProps === void 0 ) constantProps = {}; - - return checkOptionsSync(config, appProps, constantProps, validateSync) - } - }; - - // export - // PIA syntax - var isObject$1 = checkIsObject; - var isString$1 = checkIsString; - - var createConfig$1 = createConfig; - var checkConfig$1 = checkConfig(validateSync); - - // 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 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}); - }); - }) - } - - /** - * The code was extracted from: - * https://github.com/davidchambers/Base64.js - */ - - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - - function InvalidCharacterError(message) { - this.message = message; - } - - InvalidCharacterError.prototype = new Error(); - InvalidCharacterError.prototype.name = 'InvalidCharacterError'; - - function polyfill (input) { - var str = String(input).replace(/=+$/, ''); - if (str.length % 4 == 1) { - throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); - } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = str.charAt(idx++); - // character found in table? initialize bit storage and add its ascii value; - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = chars.indexOf(buffer); - } - return output; - } - - - var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; - - function b64DecodeUnicode(str) { - return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { - var code = p.charCodeAt(0).toString(16).toUpperCase(); - if (code.length < 2) { - code = '0' + code; - } - return '%' + code; - })); - } - - var base64_url_decode = function(str) { - var output = str.replace(/-/g, "+").replace(/_/g, "/"); - switch (output.length % 4) { - case 0: - break; - case 2: - output += "=="; - break; - case 3: - output += "="; - break; - default: - throw "Illegal base64url string!"; - } - - try{ - return b64DecodeUnicode(output); - } catch (err) { - return atob(output); - } - }; - - function InvalidTokenError(message) { - this.message = message; - } - - InvalidTokenError.prototype = new Error(); - InvalidTokenError.prototype.name = 'InvalidTokenError'; - - var lib = function (token,options) { - if (typeof token !== 'string') { - throw new InvalidTokenError('Invalid token specified'); - } - - options = options || {}; - var pos = options.header === true ? 0 : 1; - try { - return JSON.parse(base64_url_decode(token.split('.')[pos])); - } catch (e) { - throw new InvalidTokenError('Invalid token specified: ' + e.message); - } - }; - - var InvalidTokenError_1 = InvalidTokenError; - lib.InvalidTokenError = InvalidTokenError_1; - - // 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); - // we only check the exp for the time being - if (token.exp) { - if (start >= token.exp) { - var expired = new Date(token.exp).toISOString(); - throw new JsonqlError(("Token has expired on " + expired), token) - } - } - return token; - } - - /** - * The browser client version it has far fewer options and it doesn't verify it - * because it couldn't this is the job for the server - * @TODO we need to add some extra proessing here to check for the exp field - * @param {string} token to decrypted - * @return {object} decrypted object - */ - function jwtDecode(token) { - if (isString$1(token)) { - var t = lib(token); - return validate(t) - } - throw new JsonqlError('Token must be a string!') - } - - var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; - - var appProps = { - algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), - expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), - notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), - audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), - subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), - issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), - noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), - header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), - keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), - mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) - }; - - function tokenValidator(config) { - if (!isObject$1(config)) { - return {}; // we just ignore it all together? - } - var result = {}; - var opts = checkConfig$1(config, appProps); - // need to remove options that is false - for (var key in opts) { - if (opts[key]) { - result[key] = opts[key]; - } - } - return result; - } - - // ws client using native WebSocket - - function getWS() { - switch(true) { - case (typeof WebSocket !== 'undefined'): - return WebSocket; - case (typeof MozWebSocket !== 'undefined'): - return MozWebSocket; - // case (typeof global !== 'undefined'): - // return global.WebSocket || global.MozWebSocket; - case (typeof window !== 'undefined'): - return window.WebSocket || window.MozWebSocket; - // case (typeof self !== 'undefined'): - // return self.WebSocket || self.MozWebSocket; - default: - throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!') - } - } - - var WS = getWS(); - /** - * Create a client with auth token - * @param {string} url start with ws:// @TODO check this? - * @param {string} token the jwt token - * @return {object} ws instance - */ - function wsAuthClient(url, token) { - return wsClient((url + "?" + TOKEN_PARAM_NAME + "=" + token)) - } - - /** - * Also create a normal client this is for down stream to able to use in node and browser - * @NOTE CAN NOT pass an option if I do then the brower throw error - * @param {string} url end point - * @return {object} ws instance - */ - function wsClient(url) { - return new WS(url) - } - - exports.decodeToken = jwtDecode; - exports.socketIoChainConnect = socketIoChainConnect; - exports.socketIoClient = socketIoClient; - exports.socketIoClientAsync = socketIoClientAsync; - exports.socketIoHandshakeLogin = socketIoHandshakeLogin; - exports.socketIoRoundtripLogin = socketIoRoundtripLogin; - exports.tokenValidator = tokenValidator; - exports.wsAuthClient = wsAuthClient; - exports.wsClient = wsClient; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); +!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";function e(t,r,e){return void 0===e&&(e={}),t.connect(r,e)}r=r&&r.hasOwnProperty("default")?r.default:r;var n="type",o="optional",i="enumv",u="args",a="checker",f="alias",c=5e3,s="token",h="roundtip",l="handshake";function p(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return Promise.resolve(Reflect.apply(e,null,t))}function v(t,r,n,o){void 0===o&&(o={});var i,u=o.timeout||c,a=e(t,r,Object.assign({},o,{query:[s,n].join("=")}));return new Promise(function(t,r){i=setTimeout(function(){r()},u),a.on("connect",function(){console.info("socketIoHandshakeLogin connected"),t(a),clearTimeout(i)})})}var g="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},y=function(){try{if(window||document)return!0}catch(t){}return!1},d=function(){try{if(!y()&&g)return!0}catch(t){}return!1};var b=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 y()?"browser":d()?"node":"unknown"},r}(Error),w=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),_=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),m=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),j=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}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(r,e),r}(b),A=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}(b),E=function(t,r,e,n){t.emit("authenticate",{token:r}).on("authenticated",e).on("unauthorized",n)};function O(t,r,n,o){var i=e(t,r);return new Promise(function(t,r){E(i,n,function(){return t(i)},r)})}var P="object"==typeof g&&g&&g.Object===Object&&g,R="object"==typeof self&&self&&self.Object===Object&&self,T=P||R||Function("return this")(),S=T.Symbol,k=Object.prototype,U=k.hasOwnProperty,I=k.toString,B=S?S.toStringTag:void 0;var C=Object.prototype.toString;var x="[object Null]",Y="[object Undefined]",M=S?S.toStringTag:void 0;function z(t){return null==t?void 0===t?Y:x:M&&M in Object(t)?function(t){var r=U.call(t,B),e=t[B];try{t[B]=void 0;var n=!0}catch(t){}var o=I.call(t);return n&&(r?t[B]=e:delete t[B]),o}(t):function(t){return C.call(t)}(t)}function D(t){return null!=t&&"object"==typeof t}var L="[object Symbol]";function N(t){return"symbol"==typeof t||D(t)&&z(t)==L}function F(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e0){if(++jt>=bt)return arguments[0]}else jt=0;return mt.apply(void 0,arguments)});function Pt(t){return t!=t}function Rt(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 Dt(t){return null!=t&&zt(t.length)&&!tt(t)}var Lt=Object.prototype;function Nt(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||Lt)}var Ft="[object Arguments]";function Vt(t){return D(t)&&z(t)==Ft}var qt=Object.prototype,Wt=qt.hasOwnProperty,$t=qt.propertyIsEnumerable,Jt=Vt(function(){return arguments}())?Vt:function(t){return D(t)&&Wt.call(t,"callee")&&!$t.call(t,"callee")};var Ht="object"==typeof t&&t&&!t.nodeType&&t,Gt=Ht&&"object"==typeof module&&module&&!module.nodeType&&module,Zt=Gt&&Gt.exports===Ht?T.Buffer:void 0,Kt=(Zt?Zt.isBuffer:void 0)||function(){return!1},Qt={};Qt["[object Float32Array]"]=Qt["[object Float64Array]"]=Qt["[object Int8Array]"]=Qt["[object Int16Array]"]=Qt["[object Int32Array]"]=Qt["[object Uint8Array]"]=Qt["[object Uint8ClampedArray]"]=Qt["[object Uint16Array]"]=Qt["[object Uint32Array]"]=!0,Qt["[object Arguments]"]=Qt["[object Array]"]=Qt["[object ArrayBuffer]"]=Qt["[object Boolean]"]=Qt["[object DataView]"]=Qt["[object Date]"]=Qt["[object Error]"]=Qt["[object Function]"]=Qt["[object Map]"]=Qt["[object Number]"]=Qt["[object Object]"]=Qt["[object RegExp]"]=Qt["[object Set]"]=Qt["[object String]"]=Qt["[object WeakMap]"]=!1;var Xt="object"==typeof t&&t&&!t.nodeType&&t,tr=Xt&&"object"==typeof module&&module&&!module.nodeType&&module,rr=tr&&tr.exports===Xt&&P.process,er=function(){try{var t=tr&&tr.require&&tr.require("util").types;return t||rr&&rr.binding&&rr.binding("util")}catch(t){}}(),nr=er&&er.isTypedArray,or=nr?function(t){return function(r){return t(r)}}(nr):function(t){return D(t)&&zt(t.length)&&!!Qt[z(t)]},ir=Object.prototype.hasOwnProperty;function ur(t,r){var e=V(t),n=!e&&Jt(t),o=!e&&!n&&Kt(t),i=!e&&!n&&!o&&or(t),u=e||n||o||i,a=u?function(t,r){for(var e=-1,n=Array(t);++e-1},Or.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 Pr=pt(T,"Map");function Rr(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 Tr(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 Ce: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=Dn.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!H(e))return!1;var n=typeof r;return!!("number"==n?Dt(e)&&kt(r,e.length):"string"==n&&r in e)&&It(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--&&Rt(r,t[e],0)>-1;);return e}(n,o)+1).join("")}var Jn=[],Hn=[],Gn="undefined"!=typeof Uint8Array?Uint8Array:Array,Zn=!1;function Kn(){Zn=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,e=t.length;r>18&63]+Jn[o>>12&63]+Jn[o>>6&63]+Jn[63&o]);return i.join("")}function Xn(t){var r;Zn||Kn();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+=Jn[r>>2],o+=Jn[r<<4&63],o+="=="):2===n&&(r=(t[e-2]<<8)+t[e-1],o+=Jn[r>>10],o+=Jn[r>>4&63],o+=Jn[r<<2&63],o+="="),i.push(o),i.join("")}function to(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 ro(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 eo={}.toString,no=Array.isArray||function(t){return"[object Array]"==eo.call(t)};function oo(){return uo.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function io(t,r){if(oo()=oo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+oo().toString(16)+" bytes");return 0|t}function lo(t){return!(null==t||!t._isBuffer)}function po(t,r){if(lo(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 No(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return Fo(t).length;default:if(n)return No(t).length;r=(""+r).toLowerCase(),n=!0}}function vo(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 ko(this,r,e);case"utf8":case"utf-8":return Po(this,r,e);case"ascii":return To(this,r,e);case"latin1":case"binary":return So(this,r,e);case"base64":return Oo(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Uo(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function go(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function yo(t,r,e,n,o){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=o?0:t.length-1),e<0&&(e=t.length+e),e>=t.length){if(o)return-1;e=t.length-1}else if(e<0){if(!o)return-1;e=0}if("string"==typeof r&&(r=uo.from(r,n)),lo(r))return 0===r.length?-1:bo(t,r,e,n,o);if("number"==typeof r)return r&=255,uo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):bo(t,[r],e,n,o);throw new TypeError("val must be string, number or Buffer")}function bo(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 Oo(t,r,e){return 0===r&&e===t.length?Xn(t):Xn(t.slice(r,e))}function Po(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<=Ro)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+=" ... ")),""},uo.prototype.compare=function(t,r,e,n,o){if(!lo(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 wo(this,t,r,e);case"utf8":case"utf-8":return _o(this,t,r,e);case"ascii":return mo(this,t,r,e);case"latin1":case"binary":return jo(this,t,r,e);case"base64":return Ao(this,t,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Eo(this,t,r,e);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},uo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Ro=4096;function To(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 Bo(t,r,e,n,o,i){if(!lo(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>o||rt.length)throw new RangeError("Index out of range")}function Co(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 xo(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 Yo(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 Mo(t,r,e,n,o){return o||Yo(t,0,e,4),ro(t,r,e,n,23,4),e+4}function zo(t,r,e,n,o){return o||Yo(t,0,e,8),ro(t,r,e,n,52,8),e+8}uo.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},uo.prototype.readUInt8=function(t,r){return r||Io(t,1,this.length),this[t]},uo.prototype.readUInt16LE=function(t,r){return r||Io(t,2,this.length),this[t]|this[t+1]<<8},uo.prototype.readUInt16BE=function(t,r){return r||Io(t,2,this.length),this[t]<<8|this[t+1]},uo.prototype.readUInt32LE=function(t,r){return r||Io(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},uo.prototype.readUInt32BE=function(t,r){return r||Io(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},uo.prototype.readIntLE=function(t,r,e){t|=0,r|=0,e||Io(t,r,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*r)),n},uo.prototype.readIntBE=function(t,r,e){t|=0,r|=0,e||Io(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},uo.prototype.readInt8=function(t,r){return r||Io(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},uo.prototype.readInt16LE=function(t,r){r||Io(t,2,this.length);var e=this[t]|this[t+1]<<8;return 32768&e?4294901760|e:e},uo.prototype.readInt16BE=function(t,r){r||Io(t,2,this.length);var e=this[t+1]|this[t]<<8;return 32768&e?4294901760|e:e},uo.prototype.readInt32LE=function(t,r){return r||Io(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},uo.prototype.readInt32BE=function(t,r){return r||Io(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},uo.prototype.readFloatLE=function(t,r){return r||Io(t,4,this.length),to(this,t,!0,23,4)},uo.prototype.readFloatBE=function(t,r){return r||Io(t,4,this.length),to(this,t,!1,23,4)},uo.prototype.readDoubleLE=function(t,r){return r||Io(t,8,this.length),to(this,t,!0,52,8)},uo.prototype.readDoubleBE=function(t,r){return r||Io(t,8,this.length),to(this,t,!1,52,8)},uo.prototype.writeUIntLE=function(t,r,e,n){(t=+t,r|=0,e|=0,n)||Bo(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},uo.prototype.writeUInt8=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,1,255,0),uo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[r]=255&t,r+1},uo.prototype.writeUInt16LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,65535,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Co(this,t,r,!0),r+2},uo.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,65535,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Co(this,t,r,!1),r+2},uo.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,4294967295,0),uo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):xo(this,t,r,!0),r+4},uo.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,4294967295,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):xo(this,t,r,!1),r+4},uo.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Bo(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},uo.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Bo(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},uo.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,1,127,-128),uo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},uo.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,32767,-32768),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Co(this,t,r,!0),r+2},uo.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,32767,-32768),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Co(this,t,r,!1),r+2},uo.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,2147483647,-2147483648),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):xo(this,t,r,!0),r+4},uo.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):xo(this,t,r,!1),r+4},uo.prototype.writeFloatLE=function(t,r,e){return Mo(this,t,r,!0,e)},uo.prototype.writeFloatBE=function(t,r,e){return Mo(this,t,r,!1,e)},uo.prototype.writeDoubleLE=function(t,r,e){return zo(this,t,r,!0,e)},uo.prototype.writeDoubleBE=function(t,r,e){return zo(this,t,r,!1,e)},uo.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||!uo.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 Fo(t){return function(t){var r,e,n,o,i,u;Zn||Kn();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 Gn(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=Hn[t.charCodeAt(r)]<<2|Hn[t.charCodeAt(r+1)]>>4,u[f++]=255&o):1===i&&(o=Hn[t.charCodeAt(r)]<<10|Hn[t.charCodeAt(r+1)]<<4|Hn[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(Do,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Vo(t,r,e,n){for(var o=0;o=r.length||o>=t.length);++o)r[o+e]=t[o];return o}function qo(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}g.setTimeout,g.clearTimeout;var Wo=g.performance||{};Wo.now||Wo.mozNow||Wo.msNow||Wo.oNow||Wo.webkitNow;function $o(t){return!!V(t)||null!=t&&""!==$n(t)}var Jo=function(t){return!Bn(t)&&!Yn(parseFloat(t))},Ho=function(t){return""!==$n(t)&&Bn(t)},Go=function(t){return function(t){return!0===t||!1===t||D(t)&&z(t)==Cn}(t)},Zo=function(t,r){return void 0===r&&(r=!0),!Mn(t)&&""!==t&&""!==$n(t)&&(!1===r||!0===r&&!function(t){return null===t}(t))},Ko=n,Qo=o,Xo=i,ti=u,ri=a,ei=f,ni="continue",oi=function(t){switch(t){case"number":return Jo;case"string":return Ho;case"boolean":return Go;default:return Zo}},ii=function(t,r){return void 0===r&&(r=""),!!V(t)&&(""===r||""===$n(r)||!(t.filter(function(t){return!oi(r)(t)}).length>0))},ui=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},ai=function(t,r){var e=t.arg;return r.length>1?!e.filter(function(t){return!(r.length>r.filter(function(r){return!oi(r)(t)}).length)}).length:r.length>r.filter(function(t){return!ii(e,t)}).length},fi=function(t,r){if(void 0===r&&(r=null),Hr(t)){if(!r)return!0;if(ii(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=ui(t))?!ai({arg:e},r):!oi(t)(e))}).length)}).length}return!1};function ci(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}var si=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),!fi.apply(null,u);case"array"===t:return!ii(r.arg);case!1!==(e=ui(t)):return!ai(r,e);default:return!oi(t)(r.arg)}},hi=function(t,r){return Mn(t)?!0!==r.optional||Mn(r.defaultvalue)?null:r.defaultvalue:t},li=function(t,r){var e,n=Object.keys(t);return e=r,!!n.filter(function(t){return t===e}).length},pi=function(t){return!$o(t)};function vi(t,r){var e=qn(r,function(t,r){return!t[ei]});return hn(e,{})?t:function(t,r){var e={};return r=An(r),Pn(t,function(t,n,o){Ut(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}),Pn)||r})}function gi(t,r){return zn(r,function(r,e){var n,o;return Mn(t[e])||!0===r[Qo]&&pi(t[e])?Ln({},r,((n={})[ni]=!0,n)):((o={})[ti]=t[e],o[Ko]=r[Ko],o[Qo]=r[Qo]||!1,o[Xo]=r[Xo]||!1,o[ri]=r[ri]||!1,o)})}function yi(t,r){var e=function(t,r){var e=vi(t,r);return{pristineValues:zn(qn(r,function(t,r){return li(e,r)}),function(t){return t.args}),checkAgainstAppProps:qn(r,function(t,r){return!li(e,r)}),config:e}}(t,r),n=e.config,o=e.pristineValues;return[gi(n,e.checkAgainstAppProps),o]}var di=function(t){return ii(t)?t:[t]};var bi=function(t,r){return!ii(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},wi=function(t,r){try{return!!tt(r)&&r.apply(null,[t])}catch(t){return!1}};function _i(t){return function(r,e){if(r[ni])return r[ti];var n=function(t,r){var e,n=[[t[ti]],[(e={},e[Ko]=di(t[Ko]),e[Qo]=t[Qo],e)]];return Reflect.apply(r,null,n)}(r,t);if(n.length)throw ci("runValidationAction",e,r),new _(e,n);if(!1!==r[Xo]&&!bi(r[ti],r[Xo]))throw ci(Xo,r[Xo]),new w(e);if(!1!==r[ri]&&!wi(r[ti],r[ri]))throw ci(ri,r[ri]),new m(e);return r[ti]}}function mi(t,r,e,n){return void 0===t&&(t={}),Ln(function(t,r){var e=t[0],n=t[1],o=zn(e,_i(r));return Ln(o,n)}(yi(t,r),n),e)}function ji(t,r,e,c,s,h){void 0===e&&(e=!1),void 0===c&&(c=!1),void 0===s&&(s=!1),void 0===h&&(h=!1);var l={};return l[u]=t,l[n]=r,!0===e&&(l[o]=!0),ii(c)&&(l[i]=c),tt(s)&&(l[a]=s),Bn(h)&&(l[f]=h),l}var Ai=fi,Ei=Ho,Oi=function(t,r,e){void 0===e&&(e={});var n=e[o],u=e[i],c=e[a],s=e[f];return ji.apply(null,[t,r,n,u,c,s])},Pi=function(t){return function(r,e,n){return void 0===n&&(n={}),mi(r,e,n,t)}}(function(t,r,e){var n;void 0===e&&(e=!1);var o=function(t,r){if(!ii(r))throw new A("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!ii(t))throw new A("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 ci(1),t.map(function(t,e){return{arg:t,index:e,param:r[e]}});case!0===r[0].variable:ci(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:ci(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?hi(t,u):t,index:e,param:u,optional:i}});default:throw ci(5),new A("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!!$o(r)&&!(e.type.length>e.type.filter(function(r){return si(r,t)}).length)}(t):!(t.param.type.length>t.param.type.filter(function(r){return si(r,t)}).length)});return e?((n={}).error=i,n.data=o.map(function(t){return t.arg}),n):i});var Ri="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function Ti(t){this.message=t}Ti.prototype=new Error,Ti.prototype.name="InvalidCharacterError";var Si="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var r=String(t).replace(/=+$/,"");if(r.length%4==1)throw new Ti("'atob' failed: The string to be decoded is not correctly encoded.");for(var e,n,o=0,i=0,u="";n=r.charAt(i++);~n&&(e=o%4?64*e+n:n,o++%4)?u+=String.fromCharCode(255&e>>(-2*o&6)):0)n=Ri.indexOf(n);return u};var ki=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(Si(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 Si(r)}};function Ui(t){this.message=t}Ui.prototype=new Error,Ui.prototype.name="InvalidTokenError";var Ii,Bi,Ci,xi,Yi,Mi,zi,Di,Li,Ni=function(t,r){if("string"!=typeof t)throw new Ui("Invalid token specified");var e=!0===(r=r||{}).header?0:1;try{return JSON.parse(ki(t.split(".")[e]))}catch(t){throw new Ui("Invalid token specified: "+t.message)}},Fi=Ui;Ni.InvalidTokenError=Fi;var Vi={algorithm:Oi("HS256",["string"]),expiresIn:Oi(!1,["boolean","number","string"],(Ii={},Ii[f]="exp",Ii[o]=!0,Ii)),notBefore:Oi(!1,["boolean","number","string"],(Bi={},Bi[f]="nbf",Bi[o]=!0,Bi)),audience:Oi(!1,["boolean","string"],(Ci={},Ci[f]="iss",Ci[o]=!0,Ci)),subject:Oi(!1,["boolean","string"],(xi={},xi[f]="sub",xi[o]=!0,xi)),issuer:Oi(!1,["boolean","string"],(Yi={},Yi[f]="iss",Yi[o]=!0,Yi)),noTimestamp:Oi(!1,["boolean"],(Mi={},Mi[o]=!0,Mi)),header:Oi(!1,["boolean","string"],(zi={},zi[o]=!0,zi)),keyid:Oi(!1,["boolean","string"],(Di={},Di[o]=!0,Di)),mutatePayload:Oi(!1,["boolean"],(Li={},Li[o]=!0,Li))};var qi=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 j("WebSocket is NOT SUPPORTED!")}}();function Wi(t){return new qi(t)}t.decodeToken=function(t){if(Ei(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 A("Token has expired on "+e,t)}return t}(Ni(t));throw new A("Token must be a string!")},t.socketIoChainConnect=function(t,r,e,n,o,i){return void 0===o&&(o=l),new Promise(function(i,u){var a=[r,e[0]].join("");Reflect.apply(function(t){switch(console.info("client type: ",t),t){case h:return O;case l:return v;default:throw new j("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){i([n,t])}).catch(function(t){u({message:"failed on "+o,error:t})})}).catch(function(t){u({message:"failed on "+a,error:t})})})},t.socketIoClient=e,t.socketIoClientAsync=p,t.socketIoHandshakeLogin=v,t.socketIoRoundtripLogin=O,t.tokenValidator=function(t){if(!Ai(t))return{};var r={},e=Pi(t,Vi);for(var n in e)e[n]&&(r[n]=e[n]);return r},t.wsAuthClient=function(t,r){return Wi(t+"?"+s+"="+r)},t.wsClient=Wi,Object.defineProperty(t,"__esModule",{value:!0})}); diff --git a/packages/jwt/package.json b/packages/jwt/package.json index d5178c0f..b479ec02 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -51,7 +51,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.10", + "jsonql-utils": "^0.3.11", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", diff --git a/packages/jwt/src/jwt/jwt-decode.js b/packages/jwt/src/jwt/jwt-decode.js index 74fadb26..16f51d41 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 f276ce4a..37172482 100644 --- a/packages/jwt/src/jwt/jwt-token.js +++ b/packages/jwt/src/jwt/jwt-token.js @@ -1,14 +1,10 @@ const jwt = require('jsonwebtoken') const { HSA_ALGO, RSA_ALGO, BASE64_FORMAT } = require('jsonql-constants') -const { tokenValidator } = require('./decode-token') +const { buff } = require('jsonql-utils') -function buff(str, format = BASE64_FORMAT) { - if (Buffer.isBuffer(str)) { - return str - } - return new Buffer.from(str, format) -} +const { tokenValidator } = require('./decode-token') +const baseOptions = { algorithm: HSA_ALGO } /* NOTES about the options: @@ -25,9 +21,7 @@ header keyid mutatePayload */ -const baseOptions = { - algorithm: HSA_ALGO -} + /** * Generate a jwt token * @param {object} payload object -- Gitee From a7c76a6d84ea8f1653b8ca6d0439c6d5edeefcf4 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 12:19:47 +0100 Subject: [PATCH 32/59] export the rest from the middleware for jsonql-utils --- .../jwt/src/client/decode-token/decode-token.js | 4 ++-- packages/utils/es.js | 16 ++++++++++++++-- packages/utils/package.json | 2 +- packages/utils/src/node.js | 15 --------------- 4 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 packages/utils/src/node.js diff --git a/packages/jwt/src/client/decode-token/decode-token.js b/packages/jwt/src/client/decode-token/decode-token.js index 30774d02..3c92b0bf 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/utils/es.js b/packages/utils/es.js index 7c02ef6b..756e66ca 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -28,7 +28,13 @@ import { getCallMethod, getPathToFn, packResult, - packError + packError, + resultHandler, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl } from './src/middleware' import { createQuery, @@ -41,7 +47,7 @@ import { getMutationFromPayload, getNameFromPayload } from './src/params-api' -import { buff } from './src/node' +import { buff } from './src/jwt' // alias const isContract = checkIsContract; // exports @@ -82,6 +88,12 @@ export { getPathToFn, packResult, packError, + resultHandler, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, // params-api createQuery, createQueryStr, diff --git a/packages/utils/package.json b/packages/utils/package.json index 0e2c09d0..87283769 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.11", + "version": "0.3.12", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/node.js b/packages/utils/src/node.js deleted file mode 100644 index 8e5fd990..00000000 --- a/packages/utils/src/node.js +++ /dev/null @@ -1,15 +0,0 @@ -// node env methods -import { BASE64_FORMAT } from 'jsonql-constants' - -/** - * create buffer string if it's not - * @param {string} str to create buffer - * @param {string} [format = BASE64_FORMAT] what format to use - * @return {buffer} string - */ -export function buff(str, format = BASE64_FORMAT) { - if (Buffer.isBuffer(str)) { - return str - } - return new Buffer.from(str, format) -} -- Gitee From e70ef6046ea3738a74f0344067bccd6cb0c74e2e Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 13:43:25 +0100 Subject: [PATCH 33/59] remove reference for the socket.io and ws from the jsonql-jwt --- packages/jwt/index.js | 27 +++------------------------ packages/jwt/main.js | 18 ------------------ packages/jwt/package.json | 4 ++-- packages/jwt/src/client/index.js | 19 ++++++++----------- packages/jwt/src/server/index.js | 27 +++------------------------ 5 files changed, 16 insertions(+), 79 deletions(-) diff --git a/packages/jwt/index.js b/packages/jwt/index.js index ebd322b0..a26151c2 100644 --- a/packages/jwt/index.js +++ b/packages/jwt/index.js @@ -1,31 +1,10 @@ // main export interface for client side modules import { - socketIoClient, - socketIoClientAsync, - socketIoHandshakeLogin, - socketIoRoundtripLogin, - socketIoChainConnect, - decodeToken, - tokenValidator, - - wsAuthClient, - wsClient -} from './src/client'; - -// moved to jsonql-utils -// import { groupByNamespace, chainPromises } from './src/client/utils' + tokenValidator +} from './src/client' export { - socketIoClient, - socketIoClientAsync, - socketIoHandshakeLogin, - socketIoRoundtripLogin, - socketIoChainConnect, - decodeToken, - tokenValidator, - - wsAuthClient, - wsClient + tokenValidator } diff --git a/packages/jwt/main.js b/packages/jwt/main.js index 8a747e4d..fe48fdf2 100644 --- a/packages/jwt/main.js +++ b/packages/jwt/main.js @@ -10,17 +10,7 @@ const jwtRsaToken = require('./src/jwt/jwt-rsa-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, diff --git a/packages/jwt/package.json b/packages/jwt/package.json index b479ec02..9e982795 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,7 +1,7 @@ { "name": "jsonql-jwt", - "version": "1.2.7", - "description": "jwt authentication helpers library for jsonql browser / node / socket clients", + "version": "1.3.0", + "description": "jwt authentication helpers library for jsonql browser / node", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-jwt.js", diff --git a/packages/jwt/src/client/index.js b/packages/jwt/src/client/index.js index a67ef035..75892232 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/server/index.js b/packages/jwt/src/server/index.js index 945fd80e..9a2802a2 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 -- Gitee From 1aaf7e6bb21c135b7efe00df7b86efd37e99e6ca Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:14:02 +0100 Subject: [PATCH 34/59] remove the build socket.io rollup reference --- packages/jwt/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/jwt/package.json b/packages/jwt/package.json index 9e982795..cfc2299b 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -8,11 +8,9 @@ "scripts": { "test": "npm run build:clients && 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", "build:decode": "rollup -c ./rollup.decode-jwt.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", -- Gitee From 2c6908f4e695001bdc57b309bdb0f6240ef97ba3 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:20:35 +0100 Subject: [PATCH 35/59] move around the jsonql-utils methods internally to make more sense --- packages/utils/es.js | 33 +++++++++-------- packages/utils/src/generic.js | 60 ++++++++++++++++++++++++++++++- packages/utils/src/middleware.js | 62 ++------------------------------ 3 files changed, 80 insertions(+), 75 deletions(-) diff --git a/packages/utils/es.js b/packages/utils/es.js index 756e66ca..25e2c335 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -10,7 +10,18 @@ import { extractParamsFromContract } from './src/contract' import { replaceErrors, printError } from './src/error' -import { getDebug, inArray, isKeyInObject, injectToFn } from './src/generic' +import { + getDebug, + inArray, + isKeyInObject, + injectToFn, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, + dasherize +} from './src/generic' import { isJsonqlPath, isJsonqlRequest, @@ -21,7 +32,6 @@ import { forbiddenHandler } from './src/koa' import { - dasherize, getDocLen, headerParser, isHeaderPresent, @@ -29,12 +39,7 @@ import { getPathToFn, packResult, packError, - resultHandler, - createEvt, - timestamp, - urlParams, - cacheBurst, - cacheBurstUrl + resultHandler } from './src/middleware' import { createQuery, @@ -71,6 +76,12 @@ export { inArray, isKeyInObject, injectToFn, + dasherize, + createEvt, + timestamp, + urlParams, + cacheBurst, + cacheBurstUrl, // koa isJsonqlPath, isJsonqlRequest, @@ -80,7 +91,6 @@ export { ctxErrorHandler, forbiddenHandler, // middleware - dasherize, getDocLen, headerParser, isHeaderPresent, @@ -89,11 +99,6 @@ export { packResult, packError, resultHandler, - createEvt, - timestamp, - urlParams, - cacheBurst, - cacheBurstUrl, // params-api createQuery, createQueryStr, diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 5040d5c0..053d48c2 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -47,6 +47,64 @@ export function injectToFn(resolver, name, data, overwrite = false) { 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/utils/src/middleware.js b/packages/utils/src/middleware.js index 87b99891..5c7ee99e 100644 --- a/packages/utils/src/middleware.js +++ b/packages/utils/src/middleware.js @@ -16,21 +16,7 @@ import { EXT } from 'jsonql-constants' const DOT = '.' -import { isKeyInObject } from './generic' - -/** - * 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() -) +import { isKeyInObject, timestamp, dasherize } from './generic' /** * Get document (string) byte length for use in header @@ -141,49 +127,5 @@ export const packError = function(detail, className = 'JsonqlError', statusCode * @return {object} strip the data part out, or if the error is presented */ export const resultHandler = result => ( - (checkKeyInObject(result, DATA_KEY) && !checkKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result + (isKeyInObject(result, DATA_KEY) && !isKeyInObject(result, ERROR_KEY)) ? result[DATA_KEY] : result ) - -/** - * 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() }) -- Gitee From 1676a0bd67aa4bf0c0005cd303a55c8ed6b420c7 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:28:26 +0100 Subject: [PATCH 36/59] fix the wrong interface name in the base64 encode and decode --- .../socketio}/rollup.socket-io-client.config.js | 0 packages/jwt/package.json | 2 +- packages/utils/package.json | 2 +- packages/utils/src/jwt.js | 8 ++++---- 4 files changed, 6 insertions(+), 6 deletions(-) rename packages/{jwt => @jsonql/socketio}/rollup.socket-io-client.config.js (100%) diff --git a/packages/jwt/rollup.socket-io-client.config.js b/packages/@jsonql/socketio/rollup.socket-io-client.config.js similarity index 100% rename from packages/jwt/rollup.socket-io-client.config.js rename to packages/@jsonql/socketio/rollup.socket-io-client.config.js diff --git a/packages/jwt/package.json b/packages/jwt/package.json index cfc2299b..002af95c 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -49,7 +49,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.11", + "jsonql-utils": "^0.3.12", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", diff --git a/packages/utils/package.json b/packages/utils/package.json index 87283769..f72d9f1f 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.12", + "version": "0.3.13", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/jwt.js b/packages/utils/src/jwt.js index c6266292..66897bd9 100644 --- a/packages/utils/src/jwt.js +++ b/packages/utils/src/jwt.js @@ -15,14 +15,14 @@ export function buff(str, format = BASE64_FORMAT) { /** * encode in base64 string - * @param {*} in target + * @param {*} str target * @return {string} base64 encoded */ -export 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 */ -export const base64Decode = in => decodeURIComponent(escape(window.atob(str))) +export const base64Decode = json => decodeURIComponent(escape(window.atob(json))) -- Gitee From 78fab4b9b5a554b05a590680359f2f64e63fcfd8 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:34:52 +0100 Subject: [PATCH 37/59] fix a wrong import from the generic --- packages/jwt/dist/jsonql-jwt.js | 2 +- packages/jwt/package.json | 2 +- packages/jwt/src/jwt/decode-token.js | 2013 +++++++++++++++++++++++++- packages/utils/package.json | 2 +- packages/utils/src/koa.js | 2 +- 5 files changed, 2006 insertions(+), 15 deletions(-) diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index b5deca9c..e0045bcc 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,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlJwt={},t.debug)}(this,function(t,r){"use strict";function e(t,r,e){return void 0===e&&(e={}),t.connect(r,e)}r=r&&r.hasOwnProperty("default")?r.default:r;var n="type",o="optional",i="enumv",u="args",a="checker",f="alias",c=5e3,s="token",h="roundtip",l="handshake";function p(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return Promise.resolve(Reflect.apply(e,null,t))}function v(t,r,n,o){void 0===o&&(o={});var i,u=o.timeout||c,a=e(t,r,Object.assign({},o,{query:[s,n].join("=")}));return new Promise(function(t,r){i=setTimeout(function(){r()},u),a.on("connect",function(){console.info("socketIoHandshakeLogin connected"),t(a),clearTimeout(i)})})}var g="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},y=function(){try{if(window||document)return!0}catch(t){}return!1},d=function(){try{if(!y()&&g)return!0}catch(t){}return!1};var b=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 y()?"browser":d()?"node":"unknown"},r}(Error),w=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),_=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),m=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),j=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}};return e.name.get=function(){return"JsonqlValidationError"},Object.defineProperties(r,e),r}(b),A=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}(b),E=function(t,r,e,n){t.emit("authenticate",{token:r}).on("authenticated",e).on("unauthorized",n)};function O(t,r,n,o){var i=e(t,r);return new Promise(function(t,r){E(i,n,function(){return t(i)},r)})}var P="object"==typeof g&&g&&g.Object===Object&&g,R="object"==typeof self&&self&&self.Object===Object&&self,T=P||R||Function("return this")(),S=T.Symbol,k=Object.prototype,U=k.hasOwnProperty,I=k.toString,B=S?S.toStringTag:void 0;var C=Object.prototype.toString;var x="[object Null]",Y="[object Undefined]",M=S?S.toStringTag:void 0;function z(t){return null==t?void 0===t?Y:x:M&&M in Object(t)?function(t){var r=U.call(t,B),e=t[B];try{t[B]=void 0;var n=!0}catch(t){}var o=I.call(t);return n&&(r?t[B]=e:delete t[B]),o}(t):function(t){return C.call(t)}(t)}function D(t){return null!=t&&"object"==typeof t}var L="[object Symbol]";function N(t){return"symbol"==typeof t||D(t)&&z(t)==L}function F(t,r){for(var e=-1,n=null==t?0:t.length,o=Array(n);++e0){if(++jt>=bt)return arguments[0]}else jt=0;return mt.apply(void 0,arguments)});function Pt(t){return t!=t}function Rt(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 Dt(t){return null!=t&&zt(t.length)&&!tt(t)}var Lt=Object.prototype;function Nt(t){var r=t&&t.constructor;return t===("function"==typeof r&&r.prototype||Lt)}var Ft="[object Arguments]";function Vt(t){return D(t)&&z(t)==Ft}var qt=Object.prototype,Wt=qt.hasOwnProperty,$t=qt.propertyIsEnumerable,Jt=Vt(function(){return arguments}())?Vt:function(t){return D(t)&&Wt.call(t,"callee")&&!$t.call(t,"callee")};var Ht="object"==typeof t&&t&&!t.nodeType&&t,Gt=Ht&&"object"==typeof module&&module&&!module.nodeType&&module,Zt=Gt&&Gt.exports===Ht?T.Buffer:void 0,Kt=(Zt?Zt.isBuffer:void 0)||function(){return!1},Qt={};Qt["[object Float32Array]"]=Qt["[object Float64Array]"]=Qt["[object Int8Array]"]=Qt["[object Int16Array]"]=Qt["[object Int32Array]"]=Qt["[object Uint8Array]"]=Qt["[object Uint8ClampedArray]"]=Qt["[object Uint16Array]"]=Qt["[object Uint32Array]"]=!0,Qt["[object Arguments]"]=Qt["[object Array]"]=Qt["[object ArrayBuffer]"]=Qt["[object Boolean]"]=Qt["[object DataView]"]=Qt["[object Date]"]=Qt["[object Error]"]=Qt["[object Function]"]=Qt["[object Map]"]=Qt["[object Number]"]=Qt["[object Object]"]=Qt["[object RegExp]"]=Qt["[object Set]"]=Qt["[object String]"]=Qt["[object WeakMap]"]=!1;var Xt="object"==typeof t&&t&&!t.nodeType&&t,tr=Xt&&"object"==typeof module&&module&&!module.nodeType&&module,rr=tr&&tr.exports===Xt&&P.process,er=function(){try{var t=tr&&tr.require&&tr.require("util").types;return t||rr&&rr.binding&&rr.binding("util")}catch(t){}}(),nr=er&&er.isTypedArray,or=nr?function(t){return function(r){return t(r)}}(nr):function(t){return D(t)&&zt(t.length)&&!!Qt[z(t)]},ir=Object.prototype.hasOwnProperty;function ur(t,r){var e=V(t),n=!e&&Jt(t),o=!e&&!n&&Kt(t),i=!e&&!n&&!o&&or(t),u=e||n||o||i,a=u?function(t,r){for(var e=-1,n=Array(t);++e-1},Or.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 Pr=pt(T,"Map");function Rr(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 Tr(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 Ce: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=Dn.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!H(e))return!1;var n=typeof r;return!!("number"==n?Dt(e)&&kt(r,e.length):"string"==n&&r in e)&&It(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--&&Rt(r,t[e],0)>-1;);return e}(n,o)+1).join("")}var Jn=[],Hn=[],Gn="undefined"!=typeof Uint8Array?Uint8Array:Array,Zn=!1;function Kn(){Zn=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,e=t.length;r>18&63]+Jn[o>>12&63]+Jn[o>>6&63]+Jn[63&o]);return i.join("")}function Xn(t){var r;Zn||Kn();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+=Jn[r>>2],o+=Jn[r<<4&63],o+="=="):2===n&&(r=(t[e-2]<<8)+t[e-1],o+=Jn[r>>10],o+=Jn[r>>4&63],o+=Jn[r<<2&63],o+="="),i.push(o),i.join("")}function to(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 ro(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 eo={}.toString,no=Array.isArray||function(t){return"[object Array]"==eo.call(t)};function oo(){return uo.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function io(t,r){if(oo()=oo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+oo().toString(16)+" bytes");return 0|t}function lo(t){return!(null==t||!t._isBuffer)}function po(t,r){if(lo(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 No(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return Fo(t).length;default:if(n)return No(t).length;r=(""+r).toLowerCase(),n=!0}}function vo(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 ko(this,r,e);case"utf8":case"utf-8":return Po(this,r,e);case"ascii":return To(this,r,e);case"latin1":case"binary":return So(this,r,e);case"base64":return Oo(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Uo(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function go(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function yo(t,r,e,n,o){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=o?0:t.length-1),e<0&&(e=t.length+e),e>=t.length){if(o)return-1;e=t.length-1}else if(e<0){if(!o)return-1;e=0}if("string"==typeof r&&(r=uo.from(r,n)),lo(r))return 0===r.length?-1:bo(t,r,e,n,o);if("number"==typeof r)return r&=255,uo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):bo(t,[r],e,n,o);throw new TypeError("val must be string, number or Buffer")}function bo(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 Oo(t,r,e){return 0===r&&e===t.length?Xn(t):Xn(t.slice(r,e))}function Po(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<=Ro)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+=" ... ")),""},uo.prototype.compare=function(t,r,e,n,o){if(!lo(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 wo(this,t,r,e);case"utf8":case"utf-8":return _o(this,t,r,e);case"ascii":return mo(this,t,r,e);case"latin1":case"binary":return jo(this,t,r,e);case"base64":return Ao(this,t,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Eo(this,t,r,e);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},uo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Ro=4096;function To(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 Bo(t,r,e,n,o,i){if(!lo(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>o||rt.length)throw new RangeError("Index out of range")}function Co(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 xo(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 Yo(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 Mo(t,r,e,n,o){return o||Yo(t,0,e,4),ro(t,r,e,n,23,4),e+4}function zo(t,r,e,n,o){return o||Yo(t,0,e,8),ro(t,r,e,n,52,8),e+8}uo.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},uo.prototype.readUInt8=function(t,r){return r||Io(t,1,this.length),this[t]},uo.prototype.readUInt16LE=function(t,r){return r||Io(t,2,this.length),this[t]|this[t+1]<<8},uo.prototype.readUInt16BE=function(t,r){return r||Io(t,2,this.length),this[t]<<8|this[t+1]},uo.prototype.readUInt32LE=function(t,r){return r||Io(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},uo.prototype.readUInt32BE=function(t,r){return r||Io(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},uo.prototype.readIntLE=function(t,r,e){t|=0,r|=0,e||Io(t,r,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*r)),n},uo.prototype.readIntBE=function(t,r,e){t|=0,r|=0,e||Io(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},uo.prototype.readInt8=function(t,r){return r||Io(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},uo.prototype.readInt16LE=function(t,r){r||Io(t,2,this.length);var e=this[t]|this[t+1]<<8;return 32768&e?4294901760|e:e},uo.prototype.readInt16BE=function(t,r){r||Io(t,2,this.length);var e=this[t+1]|this[t]<<8;return 32768&e?4294901760|e:e},uo.prototype.readInt32LE=function(t,r){return r||Io(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},uo.prototype.readInt32BE=function(t,r){return r||Io(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},uo.prototype.readFloatLE=function(t,r){return r||Io(t,4,this.length),to(this,t,!0,23,4)},uo.prototype.readFloatBE=function(t,r){return r||Io(t,4,this.length),to(this,t,!1,23,4)},uo.prototype.readDoubleLE=function(t,r){return r||Io(t,8,this.length),to(this,t,!0,52,8)},uo.prototype.readDoubleBE=function(t,r){return r||Io(t,8,this.length),to(this,t,!1,52,8)},uo.prototype.writeUIntLE=function(t,r,e,n){(t=+t,r|=0,e|=0,n)||Bo(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},uo.prototype.writeUInt8=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,1,255,0),uo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[r]=255&t,r+1},uo.prototype.writeUInt16LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,65535,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Co(this,t,r,!0),r+2},uo.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,65535,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Co(this,t,r,!1),r+2},uo.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,4294967295,0),uo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):xo(this,t,r,!0),r+4},uo.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,4294967295,0),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):xo(this,t,r,!1),r+4},uo.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Bo(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},uo.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var o=Math.pow(2,8*e-1);Bo(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},uo.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,1,127,-128),uo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},uo.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,32767,-32768),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Co(this,t,r,!0),r+2},uo.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,2,32767,-32768),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Co(this,t,r,!1),r+2},uo.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,2147483647,-2147483648),uo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):xo(this,t,r,!0),r+4},uo.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||Bo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),uo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):xo(this,t,r,!1),r+4},uo.prototype.writeFloatLE=function(t,r,e){return Mo(this,t,r,!0,e)},uo.prototype.writeFloatBE=function(t,r,e){return Mo(this,t,r,!1,e)},uo.prototype.writeDoubleLE=function(t,r,e){return zo(this,t,r,!0,e)},uo.prototype.writeDoubleBE=function(t,r,e){return zo(this,t,r,!1,e)},uo.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||!uo.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 Fo(t){return function(t){var r,e,n,o,i,u;Zn||Kn();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 Gn(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=Hn[t.charCodeAt(r)]<<2|Hn[t.charCodeAt(r+1)]>>4,u[f++]=255&o):1===i&&(o=Hn[t.charCodeAt(r)]<<10|Hn[t.charCodeAt(r+1)]<<4|Hn[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(Do,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Vo(t,r,e,n){for(var o=0;o=r.length||o>=t.length);++o)r[o+e]=t[o];return o}function qo(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}g.setTimeout,g.clearTimeout;var Wo=g.performance||{};Wo.now||Wo.mozNow||Wo.msNow||Wo.oNow||Wo.webkitNow;function $o(t){return!!V(t)||null!=t&&""!==$n(t)}var Jo=function(t){return!Bn(t)&&!Yn(parseFloat(t))},Ho=function(t){return""!==$n(t)&&Bn(t)},Go=function(t){return function(t){return!0===t||!1===t||D(t)&&z(t)==Cn}(t)},Zo=function(t,r){return void 0===r&&(r=!0),!Mn(t)&&""!==t&&""!==$n(t)&&(!1===r||!0===r&&!function(t){return null===t}(t))},Ko=n,Qo=o,Xo=i,ti=u,ri=a,ei=f,ni="continue",oi=function(t){switch(t){case"number":return Jo;case"string":return Ho;case"boolean":return Go;default:return Zo}},ii=function(t,r){return void 0===r&&(r=""),!!V(t)&&(""===r||""===$n(r)||!(t.filter(function(t){return!oi(r)(t)}).length>0))},ui=function(t){if(t.indexOf("array.<")>-1&&t.indexOf(">")>-1){var r=t.replace("array.<","").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1},ai=function(t,r){var e=t.arg;return r.length>1?!e.filter(function(t){return!(r.length>r.filter(function(r){return!oi(r)(t)}).length)}).length:r.length>r.filter(function(t){return!ii(e,t)}).length},fi=function(t,r){if(void 0===r&&(r=null),Hr(t)){if(!r)return!0;if(ii(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=ui(t))?!ai({arg:e},r):!oi(t)(e))}).length)}).length}return!1};function ci(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}var si=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),!fi.apply(null,u);case"array"===t:return!ii(r.arg);case!1!==(e=ui(t)):return!ai(r,e);default:return!oi(t)(r.arg)}},hi=function(t,r){return Mn(t)?!0!==r.optional||Mn(r.defaultvalue)?null:r.defaultvalue:t},li=function(t,r){var e,n=Object.keys(t);return e=r,!!n.filter(function(t){return t===e}).length},pi=function(t){return!$o(t)};function vi(t,r){var e=qn(r,function(t,r){return!t[ei]});return hn(e,{})?t:function(t,r){var e={};return r=An(r),Pn(t,function(t,n,o){Ut(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}),Pn)||r})}function gi(t,r){return zn(r,function(r,e){var n,o;return Mn(t[e])||!0===r[Qo]&&pi(t[e])?Ln({},r,((n={})[ni]=!0,n)):((o={})[ti]=t[e],o[Ko]=r[Ko],o[Qo]=r[Qo]||!1,o[Xo]=r[Xo]||!1,o[ri]=r[ri]||!1,o)})}function yi(t,r){var e=function(t,r){var e=vi(t,r);return{pristineValues:zn(qn(r,function(t,r){return li(e,r)}),function(t){return t.args}),checkAgainstAppProps:qn(r,function(t,r){return!li(e,r)}),config:e}}(t,r),n=e.config,o=e.pristineValues;return[gi(n,e.checkAgainstAppProps),o]}var di=function(t){return ii(t)?t:[t]};var bi=function(t,r){return!ii(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},wi=function(t,r){try{return!!tt(r)&&r.apply(null,[t])}catch(t){return!1}};function _i(t){return function(r,e){if(r[ni])return r[ti];var n=function(t,r){var e,n=[[t[ti]],[(e={},e[Ko]=di(t[Ko]),e[Qo]=t[Qo],e)]];return Reflect.apply(r,null,n)}(r,t);if(n.length)throw ci("runValidationAction",e,r),new _(e,n);if(!1!==r[Xo]&&!bi(r[ti],r[Xo]))throw ci(Xo,r[Xo]),new w(e);if(!1!==r[ri]&&!wi(r[ti],r[ri]))throw ci(ri,r[ri]),new m(e);return r[ti]}}function mi(t,r,e,n){return void 0===t&&(t={}),Ln(function(t,r){var e=t[0],n=t[1],o=zn(e,_i(r));return Ln(o,n)}(yi(t,r),n),e)}function ji(t,r,e,c,s,h){void 0===e&&(e=!1),void 0===c&&(c=!1),void 0===s&&(s=!1),void 0===h&&(h=!1);var l={};return l[u]=t,l[n]=r,!0===e&&(l[o]=!0),ii(c)&&(l[i]=c),tt(s)&&(l[a]=s),Bn(h)&&(l[f]=h),l}var Ai=fi,Ei=Ho,Oi=function(t,r,e){void 0===e&&(e={});var n=e[o],u=e[i],c=e[a],s=e[f];return ji.apply(null,[t,r,n,u,c,s])},Pi=function(t){return function(r,e,n){return void 0===n&&(n={}),mi(r,e,n,t)}}(function(t,r,e){var n;void 0===e&&(e=!1);var o=function(t,r){if(!ii(r))throw new A("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===r.length)return[];if(!ii(t))throw new A("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 ci(1),t.map(function(t,e){return{arg:t,index:e,param:r[e]}});case!0===r[0].variable:ci(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:ci(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?hi(t,u):t,index:e,param:u,optional:i}});default:throw ci(5),new A("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!!$o(r)&&!(e.type.length>e.type.filter(function(r){return si(r,t)}).length)}(t):!(t.param.type.length>t.param.type.filter(function(r){return si(r,t)}).length)});return e?((n={}).error=i,n.data=o.map(function(t){return t.arg}),n):i});var Ri="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function Ti(t){this.message=t}Ti.prototype=new Error,Ti.prototype.name="InvalidCharacterError";var Si="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var r=String(t).replace(/=+$/,"");if(r.length%4==1)throw new Ti("'atob' failed: The string to be decoded is not correctly encoded.");for(var e,n,o=0,i=0,u="";n=r.charAt(i++);~n&&(e=o%4?64*e+n:n,o++%4)?u+=String.fromCharCode(255&e>>(-2*o&6)):0)n=Ri.indexOf(n);return u};var ki=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(Si(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 Si(r)}};function Ui(t){this.message=t}Ui.prototype=new Error,Ui.prototype.name="InvalidTokenError";var Ii,Bi,Ci,xi,Yi,Mi,zi,Di,Li,Ni=function(t,r){if("string"!=typeof t)throw new Ui("Invalid token specified");var e=!0===(r=r||{}).header?0:1;try{return JSON.parse(ki(t.split(".")[e]))}catch(t){throw new Ui("Invalid token specified: "+t.message)}},Fi=Ui;Ni.InvalidTokenError=Fi;var Vi={algorithm:Oi("HS256",["string"]),expiresIn:Oi(!1,["boolean","number","string"],(Ii={},Ii[f]="exp",Ii[o]=!0,Ii)),notBefore:Oi(!1,["boolean","number","string"],(Bi={},Bi[f]="nbf",Bi[o]=!0,Bi)),audience:Oi(!1,["boolean","string"],(Ci={},Ci[f]="iss",Ci[o]=!0,Ci)),subject:Oi(!1,["boolean","string"],(xi={},xi[f]="sub",xi[o]=!0,xi)),issuer:Oi(!1,["boolean","string"],(Yi={},Yi[f]="iss",Yi[o]=!0,Yi)),noTimestamp:Oi(!1,["boolean"],(Mi={},Mi[o]=!0,Mi)),header:Oi(!1,["boolean","string"],(zi={},zi[o]=!0,zi)),keyid:Oi(!1,["boolean","string"],(Di={},Di[o]=!0,Di)),mutatePayload:Oi(!1,["boolean"],(Li={},Li[o]=!0,Li))};var qi=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 j("WebSocket is NOT SUPPORTED!")}}();function Wi(t){return new qi(t)}t.decodeToken=function(t){if(Ei(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 A("Token has expired on "+e,t)}return t}(Ni(t));throw new A("Token must be a string!")},t.socketIoChainConnect=function(t,r,e,n,o,i){return void 0===o&&(o=l),new Promise(function(i,u){var a=[r,e[0]].join("");Reflect.apply(function(t){switch(console.info("client type: ",t),t){case h:return O;case l:return v;default:throw new j("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){i([n,t])}).catch(function(t){u({message:"failed on "+o,error:t})})}).catch(function(t){u({message:"failed on "+a,error:t})})})},t.socketIoClient=e,t.socketIoClientAsync=p,t.socketIoHandshakeLogin=v,t.socketIoRoundtripLogin=O,t.tokenValidator=function(t){if(!Ai(t))return{};var r={},e=Pi(t,Vi);for(var n in e)e[n]&&(r[n]=e[n]);return r},t.wsAuthClient=function(t,r){return Wi(t+"?"+s+"="+r)},t.wsClient=Wi,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/package.json b/packages/jwt/package.json index 002af95c..5729098d 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -49,7 +49,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.12", + "jsonql-utils": "^0.3.13", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", diff --git a/packages/jwt/src/jwt/decode-token.js b/packages/jwt/src/jwt/decode-token.js index e7422268..3e5c4cea 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/utils/package.json b/packages/utils/package.json index f72d9f1f..9948d9a6 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.13", + "version": "0.3.14", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/koa.js b/packages/utils/src/koa.js index 2cf93619..a81df504 100644 --- a/packages/utils/src/koa.js +++ b/packages/utils/src/koa.js @@ -3,7 +3,6 @@ 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 { - dasherize, getDocLen, headerParser, isHeaderPresent, @@ -12,6 +11,7 @@ import { packResult, packError } from './middleware' +import { dasherize } from './generic' /** * @TODO need to be more flexible -- Gitee From fd19598b87b7f237ea64efdb3e7ba0b5286b616a Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:40:13 +0100 Subject: [PATCH 38/59] move socket.io code to @jsonql/socketio --- .../socketio/src/client}/chain-connect-async.js | 0 .../socketio => @jsonql/socketio/src/client}/chain-connect.js | 0 .../socketio => @jsonql/socketio/src/client}/handshake-login.js | 0 .../client/socketio => @jsonql/socketio/src/client}/index.js | 0 .../socketio => @jsonql/socketio/src/client}/roundtrip-login.js | 0 .../socketio/src/client}/socket-io-client.js | 0 .../server/socketio => @jsonql/socketio/src/server}/clients.js | 0 .../socketio => @jsonql/socketio/src/server}/get-userdata.js | 0 .../socketio => @jsonql/socketio/src/server}/handshake-auth.js | 0 .../socketio/src/server}/socketio-jwt-auth.js | 0 packages/jwt/package.json | 2 +- 11 files changed, 1 insertion(+), 1 deletion(-) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/chain-connect-async.js (100%) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/chain-connect.js (100%) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/handshake-login.js (100%) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/index.js (100%) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/roundtrip-login.js (100%) rename packages/{jwt/src/client/socketio => @jsonql/socketio/src/client}/socket-io-client.js (100%) rename packages/{jwt/src/server/socketio => @jsonql/socketio/src/server}/clients.js (100%) rename packages/{jwt/src/server/socketio => @jsonql/socketio/src/server}/get-userdata.js (100%) rename packages/{jwt/src/server/socketio => @jsonql/socketio/src/server}/handshake-auth.js (100%) rename packages/{jwt/src/server/socketio => @jsonql/socketio/src/server}/socketio-jwt-auth.js (100%) diff --git a/packages/jwt/src/client/socketio/chain-connect-async.js b/packages/@jsonql/socketio/src/client/chain-connect-async.js similarity index 100% rename from packages/jwt/src/client/socketio/chain-connect-async.js rename to packages/@jsonql/socketio/src/client/chain-connect-async.js diff --git a/packages/jwt/src/client/socketio/chain-connect.js b/packages/@jsonql/socketio/src/client/chain-connect.js similarity index 100% rename from packages/jwt/src/client/socketio/chain-connect.js rename to packages/@jsonql/socketio/src/client/chain-connect.js 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/jwt/src/server/socketio/clients.js b/packages/@jsonql/socketio/src/server/clients.js similarity index 100% rename from packages/jwt/src/server/socketio/clients.js rename to packages/@jsonql/socketio/src/server/clients.js 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/jwt/package.json b/packages/jwt/package.json index 5729098d..a2601011 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -49,7 +49,7 @@ "jsonql-constants": "^1.8.0", "jsonql-errors": "^1.1.2", "jsonql-params-validator": "^1.4.4", - "jsonql-utils": "^0.3.13", + "jsonql-utils": "^0.3.14", "jsonwebtoken": "^8.5.1", "jwt-decode": "^2.2.0", "socketio-jwt": "^4.5.0", -- Gitee From 9690a54f161376b595453a67571445994af93fb5 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:41:16 +0100 Subject: [PATCH 39/59] move the ws code to @jsonql/ws --- .../{jwt/src/client/ws => @jsonql/ws/src/client}/auth-client.js | 0 packages/{jwt/src/client/ws => @jsonql/ws/src/client}/ws.js | 0 .../{jwt/src/server/ws => @jsonql/ws/src/server}/get-userdata.js | 0 .../{jwt/src/server/ws => @jsonql/ws/src/server}/verify-client.js | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename packages/{jwt/src/client/ws => @jsonql/ws/src/client}/auth-client.js (100%) rename packages/{jwt/src/client/ws => @jsonql/ws/src/client}/ws.js (100%) rename packages/{jwt/src/server/ws => @jsonql/ws/src/server}/get-userdata.js (100%) rename packages/{jwt/src/server/ws => @jsonql/ws/src/server}/verify-client.js (100%) 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 -- Gitee From 0b206f8f4a32a175b5a01b1de4f0868e6d3fd4d1 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:45:46 +0100 Subject: [PATCH 40/59] move to jwt utils test back to utils --- packages/{jwt => utils}/tests/client-utils.test.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/{jwt => utils}/tests/client-utils.test.js (100%) diff --git a/packages/jwt/tests/client-utils.test.js b/packages/utils/tests/client-utils.test.js similarity index 100% rename from packages/jwt/tests/client-utils.test.js rename to packages/utils/tests/client-utils.test.js -- Gitee From 82f161b4925966852d7318d04d82573c0f9c9a97 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:53:22 +0100 Subject: [PATCH 41/59] test passed and ready to publish jsonql-jwt to v1.3.0 --- packages/jwt/dist/jsonql-jwt.js | 7386 ++++++++++++++++++++++++++++++- packages/jwt/package.json | 2 +- 2 files changed, 7386 insertions(+), 2 deletions(-) diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index e0045bcc..0f568d0c 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1 +1,7385 @@ -!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})}); +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('debug')) : + typeof define === 'function' && define.amd ? define(['exports', 'debug'], factory) : + (global = global || self, factory(global.jsonqlJwt = {}, global.debug)); +}(this, function (exports, debug) { 'use strict'; + + debug = debug && debug.hasOwnProperty('default') ? debug['default'] : debug; + + /** + * The code was extracted from: + * https://github.com/davidchambers/Base64.js + */ + + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + + InvalidCharacterError.prototype = new Error(); + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + function polyfill (input) { + var str = String(input).replace(/=+$/, ''); + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + } + + + var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; + + function b64DecodeUnicode(str) { + return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { + var code = p.charCodeAt(0).toString(16).toUpperCase(); + if (code.length < 2) { + code = '0' + code; + } + return '%' + code; + })); + } + + var base64_url_decode = function(str) { + var output = str.replace(/-/g, "+").replace(/_/g, "/"); + switch (output.length % 4) { + case 0: + break; + case 2: + output += "=="; + break; + case 3: + output += "="; + break; + default: + throw "Illegal base64url string!"; + } + + try{ + return b64DecodeUnicode(output); + } catch (err) { + return atob(output); + } + }; + + function InvalidTokenError(message) { + this.message = message; + } + + InvalidTokenError.prototype = new Error(); + InvalidTokenError.prototype.name = 'InvalidTokenError'; + + var lib = function (token,options) { + if (typeof token !== 'string') { + throw new InvalidTokenError('Invalid token specified'); + } + + options = options || {}; + var pos = options.header === true ? 0 : 1; + try { + return JSON.parse(base64_url_decode(token.split('.')[pos])); + } catch (e) { + throw new InvalidTokenError('Invalid token specified: ' + e.message); + } + }; + + var InvalidTokenError_1 = InvalidTokenError; + lib.InvalidTokenError = InvalidTokenError_1; + + var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Built-in value references. */ + var Symbol = root.Symbol; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Built-in value references. */ + var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString$1.call(value); + } + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** Used for built-in method references. */ + var funcProto = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype, + objectProto$2 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /* Built-in method references that are verified to be native. */ + var WeakMap = getNative(root, 'WeakMap'); + + /** Built-in value references. */ + var objectCreate = Object.create; + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeNow = Date.now; + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$3.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty$2.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max; + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4; + + return value === proto; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]'; + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$5.hasOwnProperty; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty$3.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag$1 = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** Detect free variable `exports`. */ + var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports$1 && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** Used for built-in method references. */ + var objectProto$6 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$6.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$4.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); + + /** Used for built-in method references. */ + var objectProto$7 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$5 = objectProto$7.hasOwnProperty; + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$5.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** Used for built-in method references. */ + var objectProto$8 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$6 = objectProto$8.hasOwnProperty; + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$6.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /* Built-in method references that are verified to be native. */ + var nativeCreate = getNative(Object, 'create'); + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$9 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$7 = objectProto$9.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$7.call(data, key) ? data[key] : undefined; + } + + /** Used for built-in method references. */ + var objectProto$a = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$8 = objectProto$a.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; + } + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /* Built-in method references that are verified to be native. */ + var Map = getNative(root, 'Map'); + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** Used to match property names within property paths. */ + var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** Used as references for various `Number` constants. */ + var INFINITY$1 = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** Built-in value references. */ + var getPrototype = overArg(Object.getPrototypeOf, Object); + + /** `Object#toString` result references. */ + var objectTag$1 = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto$2 = Function.prototype, + objectProto$b = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$2 = funcProto$2.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$9 = objectProto$b.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString$2.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag$1) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$9.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString$2.call(Ctor) == objectCtorString; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsZWJ = '\\u200d'; + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f', + reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', + rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', + rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, + rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange$1 + ']', + rsCombo = '[' + rsComboRange$1 + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange$1 + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange$1 + ']?', + rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** Detect free variable `exports`. */ + var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; + + /** Built-in value references. */ + var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, + allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** Used for built-in method references. */ + var objectProto$c = Object.prototype; + + /** Built-in value references. */ + var propertyIsEnumerable$1 = objectProto$c.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable$1.call(object, symbol); + }); + }; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols$1 = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'); + + /* Built-in method references that are verified to be native. */ + var Promise = getNative(root, 'Promise'); + + /* Built-in method references that are verified to be native. */ + var Set = getNative(root, 'Set'); + + /** `Object#toString` result references. */ + var mapTag$1 = '[object Map]', + objectTag$2 = '[object Object]', + promiseTag = '[object Promise]', + setTag$1 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; + + var dataViewTag$1 = '[object DataView]'; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) || + (Map && getTag(new Map) != mapTag$1) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag$1) || + (WeakMap && getTag(new WeakMap) != weakMapTag$1)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag$2 ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag$1; + case mapCtorString: return mapTag$1; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag$1; + case weakMapCtorString: return weakMapTag$1; + } + } + return result; + }; + } + + var getTag$1 = getTag; + + /** Built-in value references. */ + var Uint8Array$1 = root.Uint8Array; + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED$2); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$1 = 1, + COMPARE_UNORDERED_FLAG$1 = 2; + + /** `Object#toString` result references. */ + var boolTag$1 = '[object Boolean]', + dateTag$1 = '[object Date]', + errorTag$1 = '[object Error]', + mapTag$2 = '[object Map]', + numberTag$1 = '[object Number]', + regexpTag$1 = '[object RegExp]', + setTag$2 = '[object Set]', + stringTag$1 = '[object String]', + symbolTag$1 = '[object Symbol]'; + + var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$2 = '[object DataView]'; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto$1 = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag$2: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag$1: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { + return false; + } + return true; + + case boolTag$1: + case dateTag$1: + case numberTag$1: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag$1: + return object.name == other.name && object.message == other.message; + + case regexpTag$1: + case stringTag$1: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag$2: + var convert = mapToArray; + + case setTag$2: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG$1; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag$1: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$2 = 1; + + /** Used for built-in method references. */ + var objectProto$d = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$a = objectProto$d.hasOwnProperty; + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty$a.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$3 = 1; + + /** `Object#toString` result references. */ + var argsTag$2 = '[object Arguments]', + arrayTag$1 = '[object Array]', + objectTag$3 = '[object Object]'; + + /** Used for built-in method references. */ + var objectProto$e = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$b = objectProto$e.hasOwnProperty; + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag$1 : getTag$1(object), + othTag = othIsArr ? arrayTag$1 : getTag$1(other); + + objTag = objTag == argsTag$2 ? objectTag$3 : objTag; + othTag = othTag == argsTag$2 ? objectTag$3 : othTag; + + var objIsObj = objTag == objectTag$3, + othIsObj = othTag == objectTag$3, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { + var objIsWrapped = objIsObj && hasOwnProperty$b.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty$b.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$4 = 1, + COMPARE_UNORDERED_FLAG$2 = 2; + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG$5 = 1, + COMPARE_UNORDERED_FLAG$3 = 2; + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); + }; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ + function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, baseIteratee(predicate), baseForOwn); + } + + /** `Object#toString` result references. */ + var stringTag$2 = '[object String]'; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$2); + } + + /** `Object#toString` result references. */ + var boolTag$2 = '[object Boolean]'; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag$2); + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** `Object#toString` result references. */ + var numberTag$2 = '[object Number]'; + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag$2); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN$1(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** Error message constants. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = baseIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(baseIteratee(predicate))); + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); + } + if (!string || !(chars = baseToString(chars))) { + return string; + } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } + + /** + * Check several parameter that there is something in the param + * @param {*} param input + * @return {boolean} + */ + + function notEmpty (a) { + if (isArray(a)) { + return true; + } + return a !== undefined && a !== null && trim(a) !== ''; + } + + // validator numbers + /** + * @2015-05-04 found a problem if the value is a number like string + * it will pass, so add a check if it's string before we pass to next + * @param {number} value expected value + * @return {boolean} true if OK + */ + var checkIsNumber = function(value) { + return isString(value) ? false : !isNaN$1( parseFloat(value) ) + }; + + // validate string type + /** + * @param {string} value expected value + * @return {boolean} true if OK + */ + var checkIsString = function(value) { + return (trim(value) !== '') ? isString(value) : false; + }; + + // check for boolean + /** + * @param {boolean} value expected + * @return {boolean} true if OK + */ + var checkIsBoolean = function(value) { + return isBoolean(value); + }; + + // validate any thing only check if there is something + /** + * @param {*} value the value + * @param {boolean} [checkNull=true] strict check if there is null value + * @return {boolean} true is OK + */ + var checkIsAny = function(value, checkNull) { + if ( checkNull === void 0 ) checkNull = true; + + if (!isUndefined(value) && value !== '' && trim(value) !== '') { + if (checkNull === false || (checkNull === true && !isNull(value))) { + return true; + } + } + return false; + }; + + // the core stuff to id if it's calling with jsonql + var DATA_KEY = 'data'; + var ERROR_KEY = 'error'; + var DEFAULT_TYPE = 'any'; + // for contract-cli + var KEY_WORD = 'continue'; + + var TYPE_KEY = 'type'; + var OPTIONAL_KEY = 'optional'; + var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word + var ARGS_KEY = 'args'; + var CHECKER_KEY = 'checker'; + var ALIAS_KEY = 'alias'; + + var OR_SEPERATOR = '|'; + + var STRING_TYPE = 'string'; + var BOOLEAN_TYPE = 'boolean'; + var ARRAY_TYPE = 'array'; + var OBJECT_TYPE = 'object'; + + var NUMBER_TYPE = 'number'; + var ARRAY_TYPE_LFT = 'array.<'; + var ARRAY_TYPE_RGT = '>'; + var NO_STATUS_CODE = -1; + var HSA_ALGO = 'HS256'; + + // Good practice rule - No magic number + + var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; + var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; + var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; + // @TODO the jsdoc return array. and we should also allow array syntax + var DEFAULT_TYPE$1 = DEFAULT_TYPE; + var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; + var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; + + var TYPE_KEY$1 = TYPE_KEY; + var OPTIONAL_KEY$1 = OPTIONAL_KEY; + var ENUM_KEY$1 = ENUM_KEY; + var ARGS_KEY$1 = ARGS_KEY; + var CHECKER_KEY$1 = CHECKER_KEY; + var ALIAS_KEY$1 = ALIAS_KEY; + + var ARRAY_TYPE$1 = ARRAY_TYPE; + var OBJECT_TYPE$1 = OBJECT_TYPE; + var STRING_TYPE$1 = STRING_TYPE; + var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; + var NUMBER_TYPE$1 = NUMBER_TYPE; + var KEY_WORD$1 = KEY_WORD; + var OR_SEPERATOR$1 = OR_SEPERATOR; + + // not actually in use + // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; + + // primitive types + + /** + * this is a wrapper method to call different one based on their type + * @param {string} type to check + * @return {function} a function to handle the type + */ + var combineFn = function(type) { + switch (type) { + case NUMBER_TYPE$1: + return checkIsNumber; + case STRING_TYPE$1: + return checkIsString; + case BOOLEAN_TYPE$1: + return checkIsBoolean; + default: + return checkIsAny; + } + }; + + // validate array type + + /** + * @param {array} value expected + * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well + * @return {boolean} true if OK + */ + var checkIsArray = function(value, type) { + if ( type === void 0 ) type=''; + + if (isArray(value)) { + if (type === '' || trim(type)==='') { + return true; + } + // we test it in reverse + // @TODO if the type is an array (OR) then what? + // we need to take into account this could be an array + var c = value.filter(function (v) { return !combineFn(type)(v); }); + return !(c.length > 0) + } + return false; + }; + + /** + * check if it matches the array. pattern + * @param {string} type + * @return {boolean|array} false means NO, always return array + */ + var isArrayLike$1 = function(type) { + // @TODO could that have something like array<> instead of array.<>? missing the dot? + // because type script is Array without the dot + if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { + var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); + if (_type.indexOf(OR_SEPERATOR$1)) { + return _type.split(OR_SEPERATOR$1) + } + return [_type] + } + return false; + }; + + /** + * we might encounter something like array. then we need to take it apart + * @param {object} p the prepared object for processing + * @param {string|array} type the type came from + * @return {boolean} for the filter to operate on + */ + var arrayTypeHandler = function(p, type) { + var arg = p.arg; + // need a special case to handle the OR type + // we need to test the args instead of the type(s) + if (type.length > 1) { + return !arg.filter(function (v) { return ( + !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) + ); }).length; + } + // type is array so this will be or! + return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; + }; + + // validate object type + /** + * @TODO if provide with the keys then we need to check if the key:value type as well + * @param {object} value expected + * @param {array} [keys=null] if it has the keys array to compare as well + * @return {boolean} true if OK + */ + var checkIsObject = function(value, keys) { + if ( keys === void 0 ) keys=null; + + if (isPlainObject(value)) { + if (!keys) { + return true; + } + if (checkIsArray(keys)) { + // please note we DON'T care if some is optional + // plese refer to the contract.json for the keys + return !keys.filter(function (key) { + var _value = value[key.name]; + return !(key.type.length > key.type.filter(function (type) { + var tmp; + if (!isUndefined(_value)) { + if ((tmp = isArrayLike$1(type)) !== false) { + return !arrayTypeHandler({arg: _value}, tmp) + // return tmp.filter(t => !checkIsArray(_value, t)).length; + // @TODO there might be an object within an object with keys as well :S + } + return !combineFn(type)(_value) + } + return true; + }).length) + }).length; + } + } + return false; + }; + + /** + * fold this into it's own function to handler different object type + * @param {object} p the prepared object for process + * @return {boolean} + */ + var objectTypeHandler = function(p) { + var arg = p.arg; + var param = p.param; + var _args = [arg]; + if (Array.isArray(param.keys) && param.keys.length) { + _args.push(param.keys); + } + // just simple check + return checkIsObject.apply(null, _args) + }; + + /** + * some time it's hard to tell where the error is throw from + * because client server throw the same, therefore this util fn + * to add a property to the error object to tell if it's throw + * from client or server + * + */ + + var isBrowser = function () { + try { + if (window || document) { + return true; + } + } catch(e) {} + return false; + }; + + var isNode = function () { + try { + if (!isBrowser() && global$1) { + return true; + } + } catch(e) {} + return false; + }; + + function whereAmI() { + if (isBrowser()) { + return 'browser' + } + if (isNode()) { + return 'node' + } + return 'unknown' + } + + // The base Error of all + + var JsonqlBaseError = /*@__PURE__*/(function (Error) { + function JsonqlBaseError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + } + + if ( Error ) JsonqlBaseError.__proto__ = Error; + JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); + JsonqlBaseError.prototype.constructor = JsonqlBaseError; + + JsonqlBaseError.where = function where () { + return whereAmI() + }; + + return JsonqlBaseError; + }(Error)); + + // this get throw from within the checkOptions when run through the enum failed + var JsonqlEnumError = /*@__PURE__*/(function (Error) { + function JsonqlEnumError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlEnumError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlEnumError); + } + } + + if ( Error ) JsonqlEnumError.__proto__ = Error; + JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); + JsonqlEnumError.prototype.constructor = JsonqlEnumError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlEnumError'; + }; + + Object.defineProperties( JsonqlEnumError, staticAccessors ); + + return JsonqlEnumError; + }(Error)); + + // this will throw from inside the checkOptions + var JsonqlTypeError = /*@__PURE__*/(function (Error) { + function JsonqlTypeError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlTypeError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlTypeError); + } + } + + if ( Error ) JsonqlTypeError.__proto__ = Error; + JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); + JsonqlTypeError.prototype.constructor = JsonqlTypeError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlTypeError'; + }; + + Object.defineProperties( JsonqlTypeError, staticAccessors ); + + return JsonqlTypeError; + }(Error)); + + // allow supply a custom checker function + // if that failed then we throw this error + var JsonqlCheckerError = /*@__PURE__*/(function (Error) { + function JsonqlCheckerError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + Error.apply(this, args); + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlCheckerError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlCheckerError); + } + } + + if ( Error ) JsonqlCheckerError.__proto__ = Error; + JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); + JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; + + var staticAccessors = { name: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlCheckerError'; + }; + + Object.defineProperties( JsonqlCheckerError, staticAccessors ); + + return JsonqlCheckerError; + }(Error)); + + /** + * This is a custom error to throw whenever a error happen inside the jsonql + * This help us to capture the right error, due to the call happens in sequence + * @param {string} message to tell what happen + * @param {mixed} extra things we want to add, 500? + */ + var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { + function JsonqlError() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + JsonqlBaseError.apply(this, args); + + this.message = args[0]; + this.detail = args[1]; + + this.className = JsonqlError.name; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, JsonqlError); + } + } + + if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; + JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); + JsonqlError.prototype.constructor = JsonqlError; + + var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; + + staticAccessors.name.get = function () { + return 'JsonqlError'; + }; + + staticAccessors.statusCode.get = function () { + return NO_STATUS_CODE; + }; + + Object.defineProperties( JsonqlError, staticAccessors ); + + return JsonqlError; + }(JsonqlBaseError)); + + /** + * just a simple util for helping to debug + * @param {array} args arguments + * @return {void} + */ + function log() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + try { + if (window && window.debug) { + Reflect.apply(console.log, console, args); + } + } catch(e) {} + } + + // move the index.js code here that make more sense to find where things are + // import debug from 'debug' + // const debugFn = debug('jsonql-params-validator:validator') + // also export this for use in other places + + /** + * We need to handle those optional parameter without a default value + * @param {object} params from contract.json + * @return {boolean} for filter operation false is actually OK + */ + var optionalHandler = function( params ) { + var arg = params.arg; + var param = params.param; + if (notEmpty(arg)) { + // debug('call optional handler', arg, params); + // loop through the type in param + return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } + ).length) + } + return false; + }; + + /** + * actually picking the validator + * @param {*} type for checking + * @param {*} value for checking + * @return {boolean} true on OK + */ + var validateHandler = function(type, value) { + var tmp; + switch (true) { + case type === OBJECT_TYPE$1: + // debugFn('call OBJECT_TYPE') + return !objectTypeHandler(value) + case type === ARRAY_TYPE$1: + // debugFn('call ARRAY_TYPE') + return !checkIsArray(value.arg) + // @TODO when the type is not present, it always fall through here + // so we need to find a way to actually pre-check the type first + // AKA check the contract.json map before running here + case (tmp = isArrayLike$1(type)) !== false: + // debugFn('call ARRAY_LIKE: %O', value) + return !arrayTypeHandler(value, tmp) + default: + return !combineFn(type)(value.arg) + } + }; + + /** + * it get too longer to fit in one line so break it out from the fn below + * @param {*} arg value + * @param {object} param config + * @return {*} value or apply default value + */ + var getOptionalValue = function(arg, param) { + if (!isUndefined(arg)) { + return arg; + } + return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) + }; + + /** + * padding the arguments with defaultValue if the arguments did not provide the value + * this will be the name export + * @param {array} args normalized arguments + * @param {array} params from contract.json + * @return {array} merge the two together + */ + var normalizeArgs = function(args, params) { + // first we should check if this call require a validation at all + // there will be situation where the function doesn't need args and params + if (!checkIsArray(params)) { + // debugFn('params value', params) + throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) + } + if (params.length === 0) { + return []; + } + if (!checkIsArray(args)) { + throw new JsonqlError(ARGS_NOT_ARRAY_ERR) + } + // debugFn(args, params); + // fall through switch + switch(true) { + case args.length == params.length: // standard + log(1); + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, + param: params[i] + } + ); }) + case params[0].variable === true: // using spread syntax + log(2); + var type = params[0].type; + return args.map(function (arg, i) { return ( + { + arg: arg, + index: i, // keep the index for reference + param: params[i] || { type: type, name: '_' } + } + ); }) + // with optional defaultValue parameters + case args.length < params.length: + log(3); + return params.map(function (param, i) { return ( + { + param: param, + index: i, + arg: getOptionalValue(args[i], param), + optional: param.optional || false + } + ); }) + // this one pass more than it should have anything after the args.length will be cast as any type + case args.length > params.length: + log(4); + var ctn = params.length; + // this happens when we have those array. type + var _type = [ DEFAULT_TYPE$1 ]; + // we only looking at the first one, this might be a @BUG + /* + if ((tmp = isArrayLike(params[0].type[0])) !== false) { + _type = tmp; + } */ + // if we use the params as guide then the rest will get throw out + // which is not what we want, instead, anything without the param + // will get a any type and optional flag + return args.map(function (arg, i) { + var optional = i >= ctn ? true : !!params[i].optional; + var param = params[i] || { type: _type, name: ("_" + i) }; + return { + arg: optional ? getOptionalValue(arg, param) : arg, + index: i, + param: param, + optional: optional + } + }) + // @TODO find out if there is more cases not cover + default: // this should never happen + log(5); + // debugFn('args', args) + // debugFn('params', params) + // this is unknown therefore we just throw it! + throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) + } + }; + + // what we want is after the validaton we also get the normalized result + // which is with the optional property if the argument didn't provide it + /** + * process the array of params back to their arguments + * @param {array} result the params result + * @return {array} arguments + */ + var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; + + /** + * validator main interface + * @param {array} args the arguments pass to the method call + * @param {array} params from the contract for that method + * @param {boolean} [withResul=false] if true then this will return the normalize result as well + * @return {array} empty array on success, or failed parameter and reasons + */ + var validateSync = function(args, params, withResult) { + var obj; + + if ( withResult === void 0 ) withResult = false; + var cleanArgs = normalizeArgs(args, params); + var checkResult = cleanArgs.filter(function (p) { + // v1.4.4 this fixed the problem, the root level optional is from the last fn + if (p.optional === true || p.param.optional === true) { + return optionalHandler(p) + } + // because array of types means OR so if one pass means pass + return !(p.param.type.length > p.param.type.filter( + function (type) { return validateHandler(type, p); } + ).length) + }); + // using the same convention we been using all this time + return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) + }; + + /** + * @param {array} arr Array for check + * @param {*} value target + * @return {boolean} true on successs + */ + var isInArray = function(arr, value) { + return !!arr.filter(function (a) { return a === value; }).length; + }; + + /** + * @param {object} obj for search + * @param {string} key target + * @return {boolean} true on success + */ + var checkKeyInObject = function(obj, key) { + var keys = Object.keys(obj); + return isInArray(keys, key) + }; + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:prepare') + + // just not to make my head hurt + var isEmpty = function (value) { return !notEmpty(value); }; + + /** + * Map the alias to their key then grab their value over + * @param {object} config the user supplied config + * @param {object} appProps the default option map + * @return {object} the config keys replaced with the appProps key by the ALIAS + */ + function mapAliasConfigKeys(config, appProps) { + // need to do two steps + // 1. take key with alias key + var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); + if (isEqual(aliasMap, {})) { + return config; + } + return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) + } + + /** + * We only want to run the valdiation against the config (user supplied) value + * but keep the defaultOptions untouch + * @param {object} config configuraton supplied by user + * @param {object} appProps the default options map + * @return {object} the pristine values that will add back to the final output + */ + function preservePristineValues(config, appProps) { + // @BUG this will filter out those that is alias key + // we need to first map the alias keys back to their full key + var _config = mapAliasConfigKeys(config, appProps); + // take the default value out + var pristineValues = mapValues( + omitBy(appProps, function (value, key) { return checkKeyInObject(_config, key); }), + function (value) { return value.args; } + ); + // for testing the value + var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !checkKeyInObject(_config, key); }); + // output + return { + pristineValues: pristineValues, + checkAgainstAppProps: checkAgainstAppProps, + config: _config // passing this correct values back + } + } + + /** + * This will take the value that is ONLY need to check + * @param {object} config that one + * @param {object} props map for creating checking + * @return {object} put that arg into the args + */ + function processConfigAction(config, props) { + // debugFn('processConfigAction', props) + // v.1.2.0 add checking if its mark optional and the value is empty then pass + return mapValues(props, function (value, key) { + var obj, obj$1; + + return ( + isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) + ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) + : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) + ); + } + ) + } + + /** + * Quick transform + * @TODO we should only validate those that is pass from the config + * and pass through those values that is from the defaultOptions + * @param {object} opts that one + * @param {object} appProps mutation configuration options + * @return {object} put that arg into the args + */ + function prepareArgsForValidation(opts, appProps) { + var ref = preservePristineValues(opts, appProps); + var config = ref.config; + var pristineValues = ref.pristineValues; + var checkAgainstAppProps = ref.checkAgainstAppProps; + // output + return [ + processConfigAction(config, checkAgainstAppProps), + pristineValues + ] + } + + // breaking the whole thing up to see what cause the multiple calls issue + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:validation') + + /** + * just make sure it returns an array to use + * @param {*} arg input + * @return {array} output + */ + var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; + + /** + * DIY in array + * @param {array} arr to check against + * @param {*} value to check + * @return {boolean} true on OK + */ + var inArray = function (arr, value) { return ( + !!arr.filter(function (v) { return v === value; }).length + ); }; + + /** + * break out to make the code easier to read + * @param {object} value to process + * @param {function} cb the validateSync + * @return {array} empty on success + */ + function validateHandler$1(value, cb) { + var obj; + + // cb is the validateSync methods + var args = [ + [ value[ARGS_KEY$1] ], + [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] + ]; + // debugFn('validateHandler', args) + return Reflect.apply(cb, null, args) + } + + /** + * Check against the enum value if it's provided + * @param {*} value to check + * @param {*} enumv to check against if it's not false + * @return {boolean} true on OK + */ + var enumHandler = function (value, enumv) { + if (checkIsArray(enumv)) { + return inArray(enumv, value) + } + return true; + }; + + /** + * Allow passing a function to check the value + * There might be a problem here if the function is incorrect + * and that will makes it hard to debug what is going on inside + * @TODO there could be a few feature add to this one under different circumstance + * @param {*} value to check + * @param {function} checker for checking + */ + var checkerHandler = function (value, checker) { + try { + return isFunction(checker) ? checker.apply(null, [value]) : false; + } catch (e) { + return false; + } + }; + + /** + * Taken out from the runValidaton this only validate the required values + * @param {array} args from the config2argsAction + * @param {function} cb validateSync + * @return {array} of configuration values + */ + function runValidationAction(cb) { + return function (value, key) { + // debugFn('runValidationAction', key, value) + if (value[KEY_WORD$1]) { + return value[ARGS_KEY$1] + } + var check = validateHandler$1(value, cb); + if (check.length) { + log('runValidationAction', key, value); + throw new JsonqlTypeError(key, check) + } + if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { + log(ENUM_KEY$1, value[ENUM_KEY$1]); + throw new JsonqlEnumError(key) + } + if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { + log(CHECKER_KEY$1, value[CHECKER_KEY$1]); + throw new JsonqlCheckerError(key) + } + return value[ARGS_KEY$1] + } + } + + /** + * @param {object} args from the config2argsAction + * @param {function} cb validateSync + * @return {object} of configuration values + */ + function runValidation(args, cb) { + var argsForValidate = args[0]; + var pristineValues = args[1]; + // turn the thing into an array and see what happen here + // debugFn('_args', argsForValidate) + var result = mapValues(argsForValidate, runValidationAction(cb)); + return merge(result, pristineValues) + } + + // this is port back from the client to share across all projects + + /** + * @param {object} config user provide configuration option + * @param {object} appProps mutation configuration options + * @param {object} constProps the immutable configuration options + * @param {function} cb the validateSync method + * @return {object} Promise resolve merge config object + */ + function checkOptionsSync(config, appProps, constProps, cb) { + if ( config === void 0 ) config = {}; + + return merge( + runValidation( + prepareArgsForValidation(config, appProps), + cb + ), + constProps + ); + } + + // create function to construct the config entry so we don't need to keep building object + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:construct-config'); + /** + * @param {*} args value + * @param {string} type for value + * @param {boolean} [optional=false] + * @param {boolean|array} [enumv=false] + * @param {boolean|function} [checker=false] + * @return {object} config entry + */ + function constructConfigFn(args, type, optional, enumv, checker, alias) { + if ( optional === void 0 ) optional=false; + if ( enumv === void 0 ) enumv=false; + if ( checker === void 0 ) checker=false; + if ( alias === void 0 ) alias=false; + + var base = {}; + base[ARGS_KEY] = args; + base[TYPE_KEY] = type; + if (optional === true) { + base[OPTIONAL_KEY] = true; + } + if (checkIsArray(enumv)) { + base[ENUM_KEY] = enumv; + } + if (isFunction(checker)) { + base[CHECKER_KEY] = checker; + } + if (isString(alias)) { + base[ALIAS_KEY] = alias; + } + return base; + } + + // export also create wrapper methods + + // import debug from 'debug'; + // const debugFn = debug('jsonql-params-validator:options:index'); + + /** + * This has a different interface + * @param {*} value to supply + * @param {string|array} type for checking + * @param {object} params to map against the config check + * @param {array} params.enumv NOT enum + * @param {boolean} params.optional false then nothing + * @param {function} params.checker need more work on this one later + * @param {string} params.alias mostly for cmd + */ + var createConfig = function (value, type, params) { + if ( params === void 0 ) params = {}; + + // Note the enumv not ENUM + // const { enumv, optional, checker, alias } = params; + // let args = [value, type, optional, enumv, checker, alias]; + var o = params[OPTIONAL_KEY]; + var e = params[ENUM_KEY]; + var c = params[CHECKER_KEY]; + var a = params[ALIAS_KEY]; + return constructConfigFn.apply(null, [value, type, o, e, c, a]) + }; + + // copy of above but it's sync + var checkConfig = function(validateSync) { + return function(config, appProps, constantProps) { + if ( constantProps === void 0 ) constantProps = {}; + + return checkOptionsSync(config, appProps, constantProps, validateSync) + } + }; + + // export + // PIA syntax + var isObject$1 = checkIsObject; + var isString$1 = checkIsString; + + var createConfig$1 = createConfig; + var checkConfig$1 = checkConfig(validateSync); + + // bunch of generic helpers + + /** + * @param {boolean} sec return in second or not + * @return {number} timestamp + */ + var timestamp = function (sec) { + if ( sec === void 0 ) sec = false; + + var time = Date.now(); + return sec ? Math.floor( time / 1000 ) : time; + }; + + var lookup = []; + var revLookup = []; + var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; + var inited = false; + function init () { + inited = true; + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + + revLookup['-'.charCodeAt(0)] = 62; + revLookup['_'.charCodeAt(0)] = 63; + } + + function toByteArray (b64) { + if (!inited) { + init(); + } + var i, j, l, tmp, placeHolders, arr; + var len = b64.length; + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len; + + var L = 0; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; + arr[L++] = (tmp >> 16) & 0xFF; + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); + arr[L++] = tmp & 0xFF; + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + return arr + } + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] + } + + function encodeChunk (uint8, start, end) { + var tmp; + var output = []; + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output.push(tripletToBase64(tmp)); + } + return output.join('') + } + + function fromByteArray (uint8) { + if (!inited) { + init(); + } + var tmp; + var len = uint8.length; + var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes + var output = ''; + var parts = []; + var maxChunkLength = 16383; // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1]; + output += lookup[tmp >> 2]; + output += lookup[(tmp << 4) & 0x3F]; + output += '=='; + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); + output += lookup[tmp >> 10]; + output += lookup[(tmp >> 4) & 0x3F]; + output += lookup[(tmp << 2) & 0x3F]; + output += '='; + } + + parts.push(output); + + return parts.join('') + } + + function read (buffer, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? (nBytes - 1) : 0; + var d = isLE ? -1 : 1; + var s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) + } + + function write (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); + var i = isLE ? 0 : (nBytes - 1); + var d = isLE ? 1 : -1; + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; + } + + var toString$1 = {}.toString; + + var isArray$1 = Array.isArray || function (arr) { + return toString$1.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$2.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + + function kMaxLength () { + return Buffer$2.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff + } + + function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer$2.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer$2(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$2 (arg, encodingOrOffset, length) { + if (!Buffer$2.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer$2)) { + return new Buffer$2(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$1(this, arg) + } + return from(this, arg, encodingOrOffset, length) + } + + Buffer$2.poolSize = 8192; // not used by this implementation + + // TODO: Legacy, not needed anymore. Remove in next major version. + Buffer$2._augment = function (arr) { + arr.__proto__ = Buffer$2.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$2.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) + }; + + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + Buffer$2.prototype.__proto__ = Uint8Array.prototype; + Buffer$2.__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$2.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) + }; + + function allocUnsafe$1 (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer$2.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$2.allocUnsafe = function (size) { + return allocUnsafe$1(null, size) + }; + /** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ + Buffer$2.allocUnsafeSlow = function (size) { + return allocUnsafe$1(null, size) + }; + + function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer$2.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$2.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer$2.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$1(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$2.isBuffer = isBuffer$1; + function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) + } + + Buffer$2.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$2.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$2.concat = function concat (list, length) { + if (!isArray$1(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer$2.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer$2.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$2.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$2.prototype._isBuffer = true; + + function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; + } + + Buffer$2.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$2.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$2.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$2.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$2.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } + if (this === b) { return true } + return Buffer$2.compare(this, b) === 0 + }; + + Buffer$2.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$2.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$2.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$2.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$2.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 + }; + + Buffer$2.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) + }; + + Buffer$2.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$2.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$2.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$2.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$2.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer$2.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer$2(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$2.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$2.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$2.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 1, this.length); } + return this[offset] + }; + + Buffer$2.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return this[offset] | (this[offset + 1] << 8) + }; + + Buffer$2.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 2, this.length); } + return (this[offset] << 8) | this[offset + 1] + }; + + Buffer$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, true, 23, 4) + }; + + Buffer$2.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 4, this.length); } + return read(this, offset, false, 23, 4) + }; + + Buffer$2.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) { checkOffset(offset, 8, this.length); } + return read(this, offset, true, 52, 8) + }; + + Buffer$2.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$2.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$2.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$2.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } + if (!Buffer$2.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$2.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer$2.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } + if (Buffer$2.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$2.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer$2.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$2.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } + if (Buffer$2.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$2.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$2.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$2.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } + if (!Buffer$2.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } + if (value < 0) { value = 0xff + value + 1; } + this[offset] = (value & 0xff); + return offset + 1 + }; + + Buffer$2.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer$2.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } + if (Buffer$2.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 + }; + + Buffer$2.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } + if (Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) + }; + + Buffer$2.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$2.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) + }; + + Buffer$2.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) + }; + + // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) + Buffer$2.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$2.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$2.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$2.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$2(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$1(obj) { + return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) + } + + function isFastBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) + } + + // For Node v0.10 support. Remove this eventually. + function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) + } + + if (typeof global$1.setTimeout === 'function') ; + if (typeof global$1.clearTimeout === 'function') ; + + // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js + var performance = global$1.performance || {}; + var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + + // when the user is login with the jwt + /** + * We only check the nbf and exp + * @param {object} token for checking + * @return {object} token on success + */ + function validate(token) { + var start = token.iat || timestamp(); + // we only check the exp for the time being + if (token.exp) { + if (start >= token.exp) { + var expired = new Date(token.exp).toISOString(); + throw new JsonqlError(("Token has expired on " + expired), token) + } + } + return token; + } + + /** + * The browser client version it has far fewer options and it doesn't verify it + * because it couldn't this is the job for the server + * @TODO we need to add some extra proessing here to check for the exp field + * @param {string} token to decrypted + * @return {object} decrypted object + */ + function jwtDecode(token) { + if (isString$1(token)) { + var t = lib(token); + return validate(t) + } + throw new JsonqlError('Token must be a string!') + } + + var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; + + var appProps = { + algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), + expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), + notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), + audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), + subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), + issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), + noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), + header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), + keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), + mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) + }; + + function tokenValidator(config) { + if (!isObject$1(config)) { + return {}; // we just ignore it all together? + } + var result = {}; + var opts = checkConfig$1(config, appProps); + // need to remove options that is false + for (var key in opts) { + if (opts[key]) { + result[key] = opts[key]; + } + } + return result; + } + + exports.decodeToken = jwtDecode; + exports.tokenValidator = tokenValidator; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); diff --git a/packages/jwt/package.json b/packages/jwt/package.json index a2601011..e3553311 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -6,7 +6,7 @@ "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:decode && npm run build:main", "build:main": "rollup -c", -- Gitee From f3f44f8d23dda13abc19d8a0df6f7223ef01673c Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:54:25 +0100 Subject: [PATCH 42/59] new jsonql-jwt build without all the socket client and server code --- packages/jwt/dist/jsonql-jwt.js | 7386 +------------------------------ 1 file changed, 1 insertion(+), 7385 deletions(-) diff --git a/packages/jwt/dist/jsonql-jwt.js b/packages/jwt/dist/jsonql-jwt.js index 0f568d0c..e0045bcc 100644 --- a/packages/jwt/dist/jsonql-jwt.js +++ b/packages/jwt/dist/jsonql-jwt.js @@ -1,7385 +1 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('debug')) : - typeof define === 'function' && define.amd ? define(['exports', 'debug'], factory) : - (global = global || self, factory(global.jsonqlJwt = {}, global.debug)); -}(this, function (exports, debug) { 'use strict'; - - debug = debug && debug.hasOwnProperty('default') ? debug['default'] : debug; - - /** - * The code was extracted from: - * https://github.com/davidchambers/Base64.js - */ - - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - - function InvalidCharacterError(message) { - this.message = message; - } - - InvalidCharacterError.prototype = new Error(); - InvalidCharacterError.prototype.name = 'InvalidCharacterError'; - - function polyfill (input) { - var str = String(input).replace(/=+$/, ''); - if (str.length % 4 == 1) { - throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); - } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = str.charAt(idx++); - // character found in table? initialize bit storage and add its ascii value; - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = chars.indexOf(buffer); - } - return output; - } - - - var atob = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill; - - function b64DecodeUnicode(str) { - return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) { - var code = p.charCodeAt(0).toString(16).toUpperCase(); - if (code.length < 2) { - code = '0' + code; - } - return '%' + code; - })); - } - - var base64_url_decode = function(str) { - var output = str.replace(/-/g, "+").replace(/_/g, "/"); - switch (output.length % 4) { - case 0: - break; - case 2: - output += "=="; - break; - case 3: - output += "="; - break; - default: - throw "Illegal base64url string!"; - } - - try{ - return b64DecodeUnicode(output); - } catch (err) { - return atob(output); - } - }; - - function InvalidTokenError(message) { - this.message = message; - } - - InvalidTokenError.prototype = new Error(); - InvalidTokenError.prototype.name = 'InvalidTokenError'; - - var lib = function (token,options) { - if (typeof token !== 'string') { - throw new InvalidTokenError('Invalid token specified'); - } - - options = options || {}; - var pos = options.header === true ? 0 : 1; - try { - return JSON.parse(base64_url_decode(token.split('.')[pos])); - } catch (e) { - throw new InvalidTokenError('Invalid token specified: ' + e.message); - } - }; - - var InvalidTokenError_1 = InvalidTokenError; - lib.InvalidTokenError = InvalidTokenError_1; - - var global$1 = (typeof global !== "undefined" ? global : - typeof self !== "undefined" ? self : - typeof window !== "undefined" ? window : {}); - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global$1 == 'object' && global$1 && global$1.Object === Object && global$1; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Built-in value references. */ - var Symbol = root.Symbol; - - /** Used for built-in method references. */ - var objectProto = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; - - /** Built-in value references. */ - var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; - } - - /** Used for built-in method references. */ - var objectProto$1 = Object.prototype; - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString$1 = objectProto$1.toString; - - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString$1.call(value); - } - - /** `Object#toString` result references. */ - var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - - /** Built-in value references. */ - var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined; - - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag$1 && symToStringTag$1 in Object(value)) - ? getRawTag(value) - : objectToString(value); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } - - /** `Object#toString` result references. */ - var symbolTag = '[object Symbol]'; - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } - - /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ - function identity(value) { - return value; - } - - /** `Object#toString` result references. */ - var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } - - /** Used to detect overreaching core-js shims. */ - var coreJsData = root['__core-js_shared__']; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** Used for built-in method references. */ - var funcProto = Function.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString = funcProto.toString; - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used for built-in method references. */ - var funcProto$1 = Function.prototype, - objectProto$2 = Object.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString$1 = funcProto$1.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty$1 = objectProto$2.hasOwnProperty; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /* Built-in method references that are verified to be native. */ - var WeakMap = getNative(root, 'WeakMap'); - - /** Built-in value references. */ - var objectCreate = Object.create; - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; - }()); - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 800, - HOT_SPAN = 16; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeNow = Date.now; - - /** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ - function shortOut(func) { - var count = 0, - lastCalled = 0; - - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; - } - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - var defineProperty = (function() { - try { - var func = getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} - }()); - - /** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var baseSetToString = !defineProperty ? identity : function(func, string) { - return defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(string), - 'writable': true - }); - }; - - /** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ - var setToString = shortOut(baseSetToString); - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); - } - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER = 9007199254740991; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function baseAssignValue(object, key, value) { - if (key == '__proto__' && defineProperty) { - defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** Used for built-in method references. */ - var objectProto$3 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$2 = objectProto$3.hasOwnProperty; - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty$2.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - baseAssignValue(object, key, newValue); - } else { - assignValue(object, key, newValue); - } - } - return object; - } - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeMax = Math.max; - - /** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ - function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return apply(func, this, otherArgs); - }; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - return setToString(overRest(func, start, identity), func + ''); - } - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER$1 = 9007199254740991; - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; - } - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** Used for built-in method references. */ - var objectProto$4 = Object.prototype; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4; - - return value === proto; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]'; - - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } - - /** Used for built-in method references. */ - var objectProto$5 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$3 = objectProto$5.hasOwnProperty; - - /** Built-in value references. */ - var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { - return isObjectLike(value) && hasOwnProperty$3.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; - - /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ - function stubFalse() { - return false; - } - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Built-in value references. */ - var Buffer = moduleExports ? root.Buffer : undefined; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** `Object#toString` result references. */ - var argsTag$1 = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag$1 = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** Detect free variable `exports`. */ - var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports$1 && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** Used for built-in method references. */ - var objectProto$6 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$4 = objectProto$6.hasOwnProperty; - - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$4.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } - } - return result; - } - - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeKeys = overArg(Object.keys, Object); - - /** Used for built-in method references. */ - var objectProto$7 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$5 = objectProto$7.hasOwnProperty; - - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty$5.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } - - /** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; - } - - /** Used for built-in method references. */ - var objectProto$8 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$6 = objectProto$8.hasOwnProperty; - - /** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - if (!isObject(object)) { - return nativeKeysIn(object); - } - var isProto = isPrototype(object), - result = []; - - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty$6.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); - } - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /* Built-in method references that are verified to be native. */ - var nativeCreate = getNative(Object, 'create'); - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used for built-in method references. */ - var objectProto$9 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$7 = objectProto$9.hasOwnProperty; - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty$7.call(data, key) ? data[key] : undefined; - } - - /** Used for built-in method references. */ - var objectProto$a = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$8 = objectProto$a.hasOwnProperty; - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; - return this; - } - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - this.size = 0; - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** Used for built-in method references. */ - var arrayProto = Array.prototype; - - /** Built-in value references. */ - var splice = arrayProto.splice; - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /* Built-in method references that are verified to be native. */ - var Map = getNative(root, 'Map'); - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; - } - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /** Error message constants. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Expose `MapCache`. - memoize.Cache = MapCache; - - /** Used as the maximum memoize cache size. */ - var MAX_MEMOIZE_SIZE = 500; - - /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ - function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; - } - - /** Used to match property names within property paths. */ - var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); - } - - /** Used as references for various `Number` constants. */ - var INFINITY$1 = 1 / 0; - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** Built-in value references. */ - var getPrototype = overArg(Object.getPrototypeOf, Object); - - /** `Object#toString` result references. */ - var objectTag$1 = '[object Object]'; - - /** Used for built-in method references. */ - var funcProto$2 = Function.prototype, - objectProto$b = Object.prototype; - - /** Used to resolve the decompiled source of functions. */ - var funcToString$2 = funcProto$2.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty$9 = objectProto$b.hasOwnProperty; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString$2.call(Object); - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || baseGetTag(value) != objectTag$1) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty$9.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString$2.call(Ctor) == objectCtorString; - } - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsZWJ = '\\u200d'; - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } - - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange$1 = '\\ud800-\\udfff', - rsComboMarksRange$1 = '\\u0300-\\u036f', - reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', - rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', - rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, - rsVarRange$1 = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsAstral = '[' + rsAstralRange$1 + ']', - rsCombo = '[' + rsComboRange$1 + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange$1 + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ$1 = '\\u200d'; - - /** Used to compose unicode regexes. */ - var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange$1 + ']?', - rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - this.size = 0; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - - this.size = data.size; - return result; - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var data = this.__data__; - if (data instanceof ListCache) { - var pairs = data.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; - } - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); - this.size = data.size; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /** Detect free variable `exports`. */ - var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; - - /** Built-in value references. */ - var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, - allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ - function stubArray() { - return []; - } - - /** Used for built-in method references. */ - var objectProto$c = Object.prototype; - - /** Built-in value references. */ - var propertyIsEnumerable$1 = objectProto$c.propertyIsEnumerable; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeGetSymbols = Object.getOwnPropertySymbols; - - /** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable$1.call(object, symbol); - }); - }; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeGetSymbols$1 = Object.getOwnPropertySymbols; - - /** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(root, 'DataView'); - - /* Built-in method references that are verified to be native. */ - var Promise = getNative(root, 'Promise'); - - /* Built-in method references that are verified to be native. */ - var Set = getNative(root, 'Set'); - - /** `Object#toString` result references. */ - var mapTag$1 = '[object Map]', - objectTag$2 = '[object Object]', - promiseTag = '[object Promise]', - setTag$1 = '[object Set]', - weakMapTag$1 = '[object WeakMap]'; - - var dataViewTag$1 = '[object DataView]'; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$1) || - (Map && getTag(new Map) != mapTag$1) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag$1) || - (WeakMap && getTag(new WeakMap) != weakMapTag$1)) { - getTag = function(value) { - var result = baseGetTag(value), - Ctor = result == objectTag$2 ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag$1; - case mapCtorString: return mapTag$1; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag$1; - case weakMapCtorString: return weakMapTag$1; - } - } - return result; - }; - } - - var getTag$1 = getTag; - - /** Built-in value references. */ - var Uint8Array$1 = root.Uint8Array; - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED$2); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$1 = 1, - COMPARE_UNORDERED_FLAG$1 = 2; - - /** `Object#toString` result references. */ - var boolTag$1 = '[object Boolean]', - dateTag$1 = '[object Date]', - errorTag$1 = '[object Error]', - mapTag$2 = '[object Map]', - numberTag$1 = '[object Number]', - regexpTag$1 = '[object RegExp]', - setTag$2 = '[object Set]', - stringTag$1 = '[object String]', - symbolTag$1 = '[object Symbol]'; - - var arrayBufferTag$1 = '[object ArrayBuffer]', - dataViewTag$2 = '[object DataView]'; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto$1 = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag$2: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag$1: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array$1(object), new Uint8Array$1(other))) { - return false; - } - return true; - - case boolTag$1: - case dateTag$1: - case numberTag$1: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag$1: - return object.name == other.name && object.message == other.message; - - case regexpTag$1: - case stringTag$1: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag$2: - var convert = mapToArray; - - case setTag$2: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG$1; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; - - case symbolTag$1: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$2 = 1; - - /** Used for built-in method references. */ - var objectProto$d = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$a = objectProto$d.hasOwnProperty; - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, - objProps = getAllKeys(object), - objLength = objProps.length, - othProps = getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty$a.call(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$3 = 1; - - /** `Object#toString` result references. */ - var argsTag$2 = '[object Arguments]', - arrayTag$1 = '[object Array]', - objectTag$3 = '[object Object]'; - - /** Used for built-in method references. */ - var objectProto$e = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$b = objectProto$e.hasOwnProperty; - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = objIsArr ? arrayTag$1 : getTag$1(object), - othTag = othIsArr ? arrayTag$1 : getTag$1(other); - - objTag = objTag == argsTag$2 ? objectTag$3 : objTag; - othTag = othTag == argsTag$2 ? objectTag$3 : othTag; - - var objIsObj = objTag == objectTag$3, - othIsObj = othTag == objectTag$3, - isSameTag = objTag == othTag; - - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { - var objIsWrapped = objIsObj && hasOwnProperty$b.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty$b.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$4 = 1, - COMPARE_UNORDERED_FLAG$2 = 2; - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = castPath(path, object); - - var index = -1, - length = path.length, - result = false; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; - } - length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isArguments(object)); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** Used to compose bitmasks for value comparisons. */ - var COMPARE_PARTIAL_FLAG$5 = 1, - COMPARE_UNORDERED_FLAG$3 = 2; - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); - }; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ - function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (value === undefined && !(key in object))) { - baseAssignValue(object, key, value); - } - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Gets the value at `key`, unless `key` is "__proto__" or "constructor". - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function safeGet(object, key) { - if (key === 'constructor' && typeof object[key] === 'function') { - return; - } - - if (key == '__proto__') { - return; - } - - return object[key]; - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = safeGet(object, key), - srcValue = safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray(srcValue), - isBuff = !isArr && isBuffer(srcValue), - isTyped = !isArr && !isBuff && isTypedArray(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - newValue = objValue; - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || isFunction(objValue)) { - newValue = initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - baseFor(source, function(srcValue, key) { - stack || (stack = new Stack); - if (isObject(srcValue)) { - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }, keysIn); - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to inspect. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, baseIteratee(predicate), baseForOwn); - } - - /** `Object#toString` result references. */ - var stringTag$2 = '[object String]'; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$2); - } - - /** `Object#toString` result references. */ - var boolTag$2 = '[object Boolean]'; - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && baseGetTag(value) == boolTag$2); - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are compared by strict equality, i.e. `===`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** `Object#toString` result references. */ - var numberTag$2 = '[object Number]'; - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && baseGetTag(value) == numberTag$2); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN$1(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = baseIteratee(iteratee); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, iteratee(value, key, object), value); - }); - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = baseIteratee(iteratee); - - baseForOwn(object, function(value, key, object) { - baseAssignValue(result, key, iteratee(value, key, object)); - }); - return result; - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** Error message constants. */ - var FUNC_ERROR_TEXT$1 = 'Expected a function'; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT$1); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - if (!isObject(object)) { - return object; - } - path = castPath(path, object); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]), - newValue = value; - - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = isObject(objValue) - ? objValue - : (isIndex(path[index + 1]) ? [] : {}); - } - } - assignValue(nested, key, newValue); - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} paths The property paths to pick. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, paths, predicate) { - var index = -1, - length = paths.length, - result = {}; - - while (++index < length) { - var path = paths[index], - value = baseGet(object, path); - - if (predicate(value, path)) { - baseSet(result, castPath(path, object), value); - } - } - return result; - } - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - if (object == null) { - return {}; - } - var props = arrayMap(getAllKeysIn(object), function(prop) { - return [prop]; - }); - predicate = baseIteratee(predicate); - return basePickBy(object, props, function(value, path) { - return predicate(value, path[0]); - }); - } - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(baseIteratee(predicate))); - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g; - - /** - * Removes leading and trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trim(' abc '); - * // => 'abc' - * - * _.trim('-_-abc-_-', '_-'); - * // => 'abc' - * - * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar'] - */ - function trim(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrim, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - chrSymbols = stringToArray(chars), - start = charsStartIndex(strSymbols, chrSymbols), - end = charsEndIndex(strSymbols, chrSymbols) + 1; - - return castSlice(strSymbols, start, end).join(''); - } - - /** - * Check several parameter that there is something in the param - * @param {*} param input - * @return {boolean} - */ - - function notEmpty (a) { - if (isArray(a)) { - return true; - } - return a !== undefined && a !== null && trim(a) !== ''; - } - - // validator numbers - /** - * @2015-05-04 found a problem if the value is a number like string - * it will pass, so add a check if it's string before we pass to next - * @param {number} value expected value - * @return {boolean} true if OK - */ - var checkIsNumber = function(value) { - return isString(value) ? false : !isNaN$1( parseFloat(value) ) - }; - - // validate string type - /** - * @param {string} value expected value - * @return {boolean} true if OK - */ - var checkIsString = function(value) { - return (trim(value) !== '') ? isString(value) : false; - }; - - // check for boolean - /** - * @param {boolean} value expected - * @return {boolean} true if OK - */ - var checkIsBoolean = function(value) { - return isBoolean(value); - }; - - // validate any thing only check if there is something - /** - * @param {*} value the value - * @param {boolean} [checkNull=true] strict check if there is null value - * @return {boolean} true is OK - */ - var checkIsAny = function(value, checkNull) { - if ( checkNull === void 0 ) checkNull = true; - - if (!isUndefined(value) && value !== '' && trim(value) !== '') { - if (checkNull === false || (checkNull === true && !isNull(value))) { - return true; - } - } - return false; - }; - - // the core stuff to id if it's calling with jsonql - var DATA_KEY = 'data'; - var ERROR_KEY = 'error'; - var DEFAULT_TYPE = 'any'; - // for contract-cli - var KEY_WORD = 'continue'; - - var TYPE_KEY = 'type'; - var OPTIONAL_KEY = 'optional'; - var ENUM_KEY = 'enumv'; // need to change this because enum is a reserved word - var ARGS_KEY = 'args'; - var CHECKER_KEY = 'checker'; - var ALIAS_KEY = 'alias'; - - var OR_SEPERATOR = '|'; - - var STRING_TYPE = 'string'; - var BOOLEAN_TYPE = 'boolean'; - var ARRAY_TYPE = 'array'; - var OBJECT_TYPE = 'object'; - - var NUMBER_TYPE = 'number'; - var ARRAY_TYPE_LFT = 'array.<'; - var ARRAY_TYPE_RGT = '>'; - var NO_STATUS_CODE = -1; - var HSA_ALGO = 'HS256'; - - // Good practice rule - No magic number - - var ARGS_NOT_ARRAY_ERR = "args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)"; - var PARAMS_NOT_ARRAY_ERR = "params is not an array! Did something gone wrong when you generate the contract.json?"; - var EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!'; - // @TODO the jsdoc return array. and we should also allow array syntax - var DEFAULT_TYPE$1 = DEFAULT_TYPE; - var ARRAY_TYPE_LFT$1 = ARRAY_TYPE_LFT; - var ARRAY_TYPE_RGT$1 = ARRAY_TYPE_RGT; - - var TYPE_KEY$1 = TYPE_KEY; - var OPTIONAL_KEY$1 = OPTIONAL_KEY; - var ENUM_KEY$1 = ENUM_KEY; - var ARGS_KEY$1 = ARGS_KEY; - var CHECKER_KEY$1 = CHECKER_KEY; - var ALIAS_KEY$1 = ALIAS_KEY; - - var ARRAY_TYPE$1 = ARRAY_TYPE; - var OBJECT_TYPE$1 = OBJECT_TYPE; - var STRING_TYPE$1 = STRING_TYPE; - var BOOLEAN_TYPE$1 = BOOLEAN_TYPE; - var NUMBER_TYPE$1 = NUMBER_TYPE; - var KEY_WORD$1 = KEY_WORD; - var OR_SEPERATOR$1 = OR_SEPERATOR; - - // not actually in use - // export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES; - - // primitive types - - /** - * this is a wrapper method to call different one based on their type - * @param {string} type to check - * @return {function} a function to handle the type - */ - var combineFn = function(type) { - switch (type) { - case NUMBER_TYPE$1: - return checkIsNumber; - case STRING_TYPE$1: - return checkIsString; - case BOOLEAN_TYPE$1: - return checkIsBoolean; - default: - return checkIsAny; - } - }; - - // validate array type - - /** - * @param {array} value expected - * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well - * @return {boolean} true if OK - */ - var checkIsArray = function(value, type) { - if ( type === void 0 ) type=''; - - if (isArray(value)) { - if (type === '' || trim(type)==='') { - return true; - } - // we test it in reverse - // @TODO if the type is an array (OR) then what? - // we need to take into account this could be an array - var c = value.filter(function (v) { return !combineFn(type)(v); }); - return !(c.length > 0) - } - return false; - }; - - /** - * check if it matches the array. pattern - * @param {string} type - * @return {boolean|array} false means NO, always return array - */ - var isArrayLike$1 = function(type) { - // @TODO could that have something like array<> instead of array.<>? missing the dot? - // because type script is Array without the dot - if (type.indexOf(ARRAY_TYPE_LFT$1) > -1 && type.indexOf(ARRAY_TYPE_RGT$1) > -1) { - var _type = type.replace(ARRAY_TYPE_LFT$1, '').replace(ARRAY_TYPE_RGT$1, ''); - if (_type.indexOf(OR_SEPERATOR$1)) { - return _type.split(OR_SEPERATOR$1) - } - return [_type] - } - return false; - }; - - /** - * we might encounter something like array. then we need to take it apart - * @param {object} p the prepared object for processing - * @param {string|array} type the type came from - * @return {boolean} for the filter to operate on - */ - var arrayTypeHandler = function(p, type) { - var arg = p.arg; - // need a special case to handle the OR type - // we need to test the args instead of the type(s) - if (type.length > 1) { - return !arg.filter(function (v) { return ( - !(type.length > type.filter(function (t) { return !combineFn(t)(v); }).length) - ); }).length; - } - // type is array so this will be or! - return type.length > type.filter(function (t) { return !checkIsArray(arg, t); }).length; - }; - - // validate object type - /** - * @TODO if provide with the keys then we need to check if the key:value type as well - * @param {object} value expected - * @param {array} [keys=null] if it has the keys array to compare as well - * @return {boolean} true if OK - */ - var checkIsObject = function(value, keys) { - if ( keys === void 0 ) keys=null; - - if (isPlainObject(value)) { - if (!keys) { - return true; - } - if (checkIsArray(keys)) { - // please note we DON'T care if some is optional - // plese refer to the contract.json for the keys - return !keys.filter(function (key) { - var _value = value[key.name]; - return !(key.type.length > key.type.filter(function (type) { - var tmp; - if (!isUndefined(_value)) { - if ((tmp = isArrayLike$1(type)) !== false) { - return !arrayTypeHandler({arg: _value}, tmp) - // return tmp.filter(t => !checkIsArray(_value, t)).length; - // @TODO there might be an object within an object with keys as well :S - } - return !combineFn(type)(_value) - } - return true; - }).length) - }).length; - } - } - return false; - }; - - /** - * fold this into it's own function to handler different object type - * @param {object} p the prepared object for process - * @return {boolean} - */ - var objectTypeHandler = function(p) { - var arg = p.arg; - var param = p.param; - var _args = [arg]; - if (Array.isArray(param.keys) && param.keys.length) { - _args.push(param.keys); - } - // just simple check - return checkIsObject.apply(null, _args) - }; - - /** - * some time it's hard to tell where the error is throw from - * because client server throw the same, therefore this util fn - * to add a property to the error object to tell if it's throw - * from client or server - * - */ - - var isBrowser = function () { - try { - if (window || document) { - return true; - } - } catch(e) {} - return false; - }; - - var isNode = function () { - try { - if (!isBrowser() && global$1) { - return true; - } - } catch(e) {} - return false; - }; - - function whereAmI() { - if (isBrowser()) { - return 'browser' - } - if (isNode()) { - return 'node' - } - return 'unknown' - } - - // The base Error of all - - var JsonqlBaseError = /*@__PURE__*/(function (Error) { - function JsonqlBaseError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - } - - if ( Error ) JsonqlBaseError.__proto__ = Error; - JsonqlBaseError.prototype = Object.create( Error && Error.prototype ); - JsonqlBaseError.prototype.constructor = JsonqlBaseError; - - JsonqlBaseError.where = function where () { - return whereAmI() - }; - - return JsonqlBaseError; - }(Error)); - - // this get throw from within the checkOptions when run through the enum failed - var JsonqlEnumError = /*@__PURE__*/(function (Error) { - function JsonqlEnumError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlEnumError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlEnumError); - } - } - - if ( Error ) JsonqlEnumError.__proto__ = Error; - JsonqlEnumError.prototype = Object.create( Error && Error.prototype ); - JsonqlEnumError.prototype.constructor = JsonqlEnumError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlEnumError'; - }; - - Object.defineProperties( JsonqlEnumError, staticAccessors ); - - return JsonqlEnumError; - }(Error)); - - // this will throw from inside the checkOptions - var JsonqlTypeError = /*@__PURE__*/(function (Error) { - function JsonqlTypeError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlTypeError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlTypeError); - } - } - - if ( Error ) JsonqlTypeError.__proto__ = Error; - JsonqlTypeError.prototype = Object.create( Error && Error.prototype ); - JsonqlTypeError.prototype.constructor = JsonqlTypeError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlTypeError'; - }; - - Object.defineProperties( JsonqlTypeError, staticAccessors ); - - return JsonqlTypeError; - }(Error)); - - // allow supply a custom checker function - // if that failed then we throw this error - var JsonqlCheckerError = /*@__PURE__*/(function (Error) { - function JsonqlCheckerError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - Error.apply(this, args); - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlCheckerError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlCheckerError); - } - } - - if ( Error ) JsonqlCheckerError.__proto__ = Error; - JsonqlCheckerError.prototype = Object.create( Error && Error.prototype ); - JsonqlCheckerError.prototype.constructor = JsonqlCheckerError; - - var staticAccessors = { name: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlCheckerError'; - }; - - Object.defineProperties( JsonqlCheckerError, staticAccessors ); - - return JsonqlCheckerError; - }(Error)); - - /** - * This is a custom error to throw whenever a error happen inside the jsonql - * This help us to capture the right error, due to the call happens in sequence - * @param {string} message to tell what happen - * @param {mixed} extra things we want to add, 500? - */ - var JsonqlError = /*@__PURE__*/(function (JsonqlBaseError) { - function JsonqlError() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - JsonqlBaseError.apply(this, args); - - this.message = args[0]; - this.detail = args[1]; - - this.className = JsonqlError.name; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, JsonqlError); - } - } - - if ( JsonqlBaseError ) JsonqlError.__proto__ = JsonqlBaseError; - JsonqlError.prototype = Object.create( JsonqlBaseError && JsonqlBaseError.prototype ); - JsonqlError.prototype.constructor = JsonqlError; - - var staticAccessors = { name: { configurable: true },statusCode: { configurable: true } }; - - staticAccessors.name.get = function () { - return 'JsonqlError'; - }; - - staticAccessors.statusCode.get = function () { - return NO_STATUS_CODE; - }; - - Object.defineProperties( JsonqlError, staticAccessors ); - - return JsonqlError; - }(JsonqlBaseError)); - - /** - * just a simple util for helping to debug - * @param {array} args arguments - * @return {void} - */ - function log() { - var args = [], len = arguments.length; - while ( len-- ) args[ len ] = arguments[ len ]; - - try { - if (window && window.debug) { - Reflect.apply(console.log, console, args); - } - } catch(e) {} - } - - // move the index.js code here that make more sense to find where things are - // import debug from 'debug' - // const debugFn = debug('jsonql-params-validator:validator') - // also export this for use in other places - - /** - * We need to handle those optional parameter without a default value - * @param {object} params from contract.json - * @return {boolean} for filter operation false is actually OK - */ - var optionalHandler = function( params ) { - var arg = params.arg; - var param = params.param; - if (notEmpty(arg)) { - // debug('call optional handler', arg, params); - // loop through the type in param - return !(param.type.length > param.type.filter(function (type) { return validateHandler(type, params); } - ).length) - } - return false; - }; - - /** - * actually picking the validator - * @param {*} type for checking - * @param {*} value for checking - * @return {boolean} true on OK - */ - var validateHandler = function(type, value) { - var tmp; - switch (true) { - case type === OBJECT_TYPE$1: - // debugFn('call OBJECT_TYPE') - return !objectTypeHandler(value) - case type === ARRAY_TYPE$1: - // debugFn('call ARRAY_TYPE') - return !checkIsArray(value.arg) - // @TODO when the type is not present, it always fall through here - // so we need to find a way to actually pre-check the type first - // AKA check the contract.json map before running here - case (tmp = isArrayLike$1(type)) !== false: - // debugFn('call ARRAY_LIKE: %O', value) - return !arrayTypeHandler(value, tmp) - default: - return !combineFn(type)(value.arg) - } - }; - - /** - * it get too longer to fit in one line so break it out from the fn below - * @param {*} arg value - * @param {object} param config - * @return {*} value or apply default value - */ - var getOptionalValue = function(arg, param) { - if (!isUndefined(arg)) { - return arg; - } - return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null) - }; - - /** - * padding the arguments with defaultValue if the arguments did not provide the value - * this will be the name export - * @param {array} args normalized arguments - * @param {array} params from contract.json - * @return {array} merge the two together - */ - var normalizeArgs = function(args, params) { - // first we should check if this call require a validation at all - // there will be situation where the function doesn't need args and params - if (!checkIsArray(params)) { - // debugFn('params value', params) - throw new JsonqlError(PARAMS_NOT_ARRAY_ERR) - } - if (params.length === 0) { - return []; - } - if (!checkIsArray(args)) { - throw new JsonqlError(ARGS_NOT_ARRAY_ERR) - } - // debugFn(args, params); - // fall through switch - switch(true) { - case args.length == params.length: // standard - log(1); - return args.map(function (arg, i) { return ( - { - arg: arg, - index: i, - param: params[i] - } - ); }) - case params[0].variable === true: // using spread syntax - log(2); - var type = params[0].type; - return args.map(function (arg, i) { return ( - { - arg: arg, - index: i, // keep the index for reference - param: params[i] || { type: type, name: '_' } - } - ); }) - // with optional defaultValue parameters - case args.length < params.length: - log(3); - return params.map(function (param, i) { return ( - { - param: param, - index: i, - arg: getOptionalValue(args[i], param), - optional: param.optional || false - } - ); }) - // this one pass more than it should have anything after the args.length will be cast as any type - case args.length > params.length: - log(4); - var ctn = params.length; - // this happens when we have those array. type - var _type = [ DEFAULT_TYPE$1 ]; - // we only looking at the first one, this might be a @BUG - /* - if ((tmp = isArrayLike(params[0].type[0])) !== false) { - _type = tmp; - } */ - // if we use the params as guide then the rest will get throw out - // which is not what we want, instead, anything without the param - // will get a any type and optional flag - return args.map(function (arg, i) { - var optional = i >= ctn ? true : !!params[i].optional; - var param = params[i] || { type: _type, name: ("_" + i) }; - return { - arg: optional ? getOptionalValue(arg, param) : arg, - index: i, - param: param, - optional: optional - } - }) - // @TODO find out if there is more cases not cover - default: // this should never happen - log(5); - // debugFn('args', args) - // debugFn('params', params) - // this is unknown therefore we just throw it! - throw new JsonqlError(EXCEPTION_CASE_ERR, { args: args, params: params }) - } - }; - - // what we want is after the validaton we also get the normalized result - // which is with the optional property if the argument didn't provide it - /** - * process the array of params back to their arguments - * @param {array} result the params result - * @return {array} arguments - */ - var processReturn = function (result) { return result.map(function (r) { return r.arg; }); }; - - /** - * validator main interface - * @param {array} args the arguments pass to the method call - * @param {array} params from the contract for that method - * @param {boolean} [withResul=false] if true then this will return the normalize result as well - * @return {array} empty array on success, or failed parameter and reasons - */ - var validateSync = function(args, params, withResult) { - var obj; - - if ( withResult === void 0 ) withResult = false; - var cleanArgs = normalizeArgs(args, params); - var checkResult = cleanArgs.filter(function (p) { - // v1.4.4 this fixed the problem, the root level optional is from the last fn - if (p.optional === true || p.param.optional === true) { - return optionalHandler(p) - } - // because array of types means OR so if one pass means pass - return !(p.param.type.length > p.param.type.filter( - function (type) { return validateHandler(type, p); } - ).length) - }); - // using the same convention we been using all this time - return !withResult ? checkResult : ( obj = {}, obj[ERROR_KEY] = checkResult, obj[DATA_KEY] = processReturn(cleanArgs), obj ) - }; - - /** - * @param {array} arr Array for check - * @param {*} value target - * @return {boolean} true on successs - */ - var isInArray = function(arr, value) { - return !!arr.filter(function (a) { return a === value; }).length; - }; - - /** - * @param {object} obj for search - * @param {string} key target - * @return {boolean} true on success - */ - var checkKeyInObject = function(obj, key) { - var keys = Object.keys(obj); - return isInArray(keys, key) - }; - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:prepare') - - // just not to make my head hurt - var isEmpty = function (value) { return !notEmpty(value); }; - - /** - * Map the alias to their key then grab their value over - * @param {object} config the user supplied config - * @param {object} appProps the default option map - * @return {object} the config keys replaced with the appProps key by the ALIAS - */ - function mapAliasConfigKeys(config, appProps) { - // need to do two steps - // 1. take key with alias key - var aliasMap = omitBy(appProps, function (value, k) { return !value[ALIAS_KEY$1]; } ); - if (isEqual(aliasMap, {})) { - return config; - } - return mapKeys(config, function (v, key) { return findKey(aliasMap, function (o) { return o.alias === key; }) || key; }) - } - - /** - * We only want to run the valdiation against the config (user supplied) value - * but keep the defaultOptions untouch - * @param {object} config configuraton supplied by user - * @param {object} appProps the default options map - * @return {object} the pristine values that will add back to the final output - */ - function preservePristineValues(config, appProps) { - // @BUG this will filter out those that is alias key - // we need to first map the alias keys back to their full key - var _config = mapAliasConfigKeys(config, appProps); - // take the default value out - var pristineValues = mapValues( - omitBy(appProps, function (value, key) { return checkKeyInObject(_config, key); }), - function (value) { return value.args; } - ); - // for testing the value - var checkAgainstAppProps = omitBy(appProps, function (value, key) { return !checkKeyInObject(_config, key); }); - // output - return { - pristineValues: pristineValues, - checkAgainstAppProps: checkAgainstAppProps, - config: _config // passing this correct values back - } - } - - /** - * This will take the value that is ONLY need to check - * @param {object} config that one - * @param {object} props map for creating checking - * @return {object} put that arg into the args - */ - function processConfigAction(config, props) { - // debugFn('processConfigAction', props) - // v.1.2.0 add checking if its mark optional and the value is empty then pass - return mapValues(props, function (value, key) { - var obj, obj$1; - - return ( - isUndefined(config[key]) || (value[OPTIONAL_KEY$1] === true && isEmpty(config[key])) - ? merge({}, value, ( obj = {}, obj[KEY_WORD$1] = true, obj )) - : ( obj$1 = {}, obj$1[ARGS_KEY$1] = config[key], obj$1[TYPE_KEY$1] = value[TYPE_KEY$1], obj$1[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1] || false, obj$1[ENUM_KEY$1] = value[ENUM_KEY$1] || false, obj$1[CHECKER_KEY$1] = value[CHECKER_KEY$1] || false, obj$1 ) - ); - } - ) - } - - /** - * Quick transform - * @TODO we should only validate those that is pass from the config - * and pass through those values that is from the defaultOptions - * @param {object} opts that one - * @param {object} appProps mutation configuration options - * @return {object} put that arg into the args - */ - function prepareArgsForValidation(opts, appProps) { - var ref = preservePristineValues(opts, appProps); - var config = ref.config; - var pristineValues = ref.pristineValues; - var checkAgainstAppProps = ref.checkAgainstAppProps; - // output - return [ - processConfigAction(config, checkAgainstAppProps), - pristineValues - ] - } - - // breaking the whole thing up to see what cause the multiple calls issue - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:validation') - - /** - * just make sure it returns an array to use - * @param {*} arg input - * @return {array} output - */ - var toArray = function (arg) { return checkIsArray(arg) ? arg : [arg]; }; - - /** - * DIY in array - * @param {array} arr to check against - * @param {*} value to check - * @return {boolean} true on OK - */ - var inArray = function (arr, value) { return ( - !!arr.filter(function (v) { return v === value; }).length - ); }; - - /** - * break out to make the code easier to read - * @param {object} value to process - * @param {function} cb the validateSync - * @return {array} empty on success - */ - function validateHandler$1(value, cb) { - var obj; - - // cb is the validateSync methods - var args = [ - [ value[ARGS_KEY$1] ], - [( obj = {}, obj[TYPE_KEY$1] = toArray(value[TYPE_KEY$1]), obj[OPTIONAL_KEY$1] = value[OPTIONAL_KEY$1], obj )] - ]; - // debugFn('validateHandler', args) - return Reflect.apply(cb, null, args) - } - - /** - * Check against the enum value if it's provided - * @param {*} value to check - * @param {*} enumv to check against if it's not false - * @return {boolean} true on OK - */ - var enumHandler = function (value, enumv) { - if (checkIsArray(enumv)) { - return inArray(enumv, value) - } - return true; - }; - - /** - * Allow passing a function to check the value - * There might be a problem here if the function is incorrect - * and that will makes it hard to debug what is going on inside - * @TODO there could be a few feature add to this one under different circumstance - * @param {*} value to check - * @param {function} checker for checking - */ - var checkerHandler = function (value, checker) { - try { - return isFunction(checker) ? checker.apply(null, [value]) : false; - } catch (e) { - return false; - } - }; - - /** - * Taken out from the runValidaton this only validate the required values - * @param {array} args from the config2argsAction - * @param {function} cb validateSync - * @return {array} of configuration values - */ - function runValidationAction(cb) { - return function (value, key) { - // debugFn('runValidationAction', key, value) - if (value[KEY_WORD$1]) { - return value[ARGS_KEY$1] - } - var check = validateHandler$1(value, cb); - if (check.length) { - log('runValidationAction', key, value); - throw new JsonqlTypeError(key, check) - } - if (value[ENUM_KEY$1] !== false && !enumHandler(value[ARGS_KEY$1], value[ENUM_KEY$1])) { - log(ENUM_KEY$1, value[ENUM_KEY$1]); - throw new JsonqlEnumError(key) - } - if (value[CHECKER_KEY$1] !== false && !checkerHandler(value[ARGS_KEY$1], value[CHECKER_KEY$1])) { - log(CHECKER_KEY$1, value[CHECKER_KEY$1]); - throw new JsonqlCheckerError(key) - } - return value[ARGS_KEY$1] - } - } - - /** - * @param {object} args from the config2argsAction - * @param {function} cb validateSync - * @return {object} of configuration values - */ - function runValidation(args, cb) { - var argsForValidate = args[0]; - var pristineValues = args[1]; - // turn the thing into an array and see what happen here - // debugFn('_args', argsForValidate) - var result = mapValues(argsForValidate, runValidationAction(cb)); - return merge(result, pristineValues) - } - - // this is port back from the client to share across all projects - - /** - * @param {object} config user provide configuration option - * @param {object} appProps mutation configuration options - * @param {object} constProps the immutable configuration options - * @param {function} cb the validateSync method - * @return {object} Promise resolve merge config object - */ - function checkOptionsSync(config, appProps, constProps, cb) { - if ( config === void 0 ) config = {}; - - return merge( - runValidation( - prepareArgsForValidation(config, appProps), - cb - ), - constProps - ); - } - - // create function to construct the config entry so we don't need to keep building object - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:construct-config'); - /** - * @param {*} args value - * @param {string} type for value - * @param {boolean} [optional=false] - * @param {boolean|array} [enumv=false] - * @param {boolean|function} [checker=false] - * @return {object} config entry - */ - function constructConfigFn(args, type, optional, enumv, checker, alias) { - if ( optional === void 0 ) optional=false; - if ( enumv === void 0 ) enumv=false; - if ( checker === void 0 ) checker=false; - if ( alias === void 0 ) alias=false; - - var base = {}; - base[ARGS_KEY] = args; - base[TYPE_KEY] = type; - if (optional === true) { - base[OPTIONAL_KEY] = true; - } - if (checkIsArray(enumv)) { - base[ENUM_KEY] = enumv; - } - if (isFunction(checker)) { - base[CHECKER_KEY] = checker; - } - if (isString(alias)) { - base[ALIAS_KEY] = alias; - } - return base; - } - - // export also create wrapper methods - - // import debug from 'debug'; - // const debugFn = debug('jsonql-params-validator:options:index'); - - /** - * This has a different interface - * @param {*} value to supply - * @param {string|array} type for checking - * @param {object} params to map against the config check - * @param {array} params.enumv NOT enum - * @param {boolean} params.optional false then nothing - * @param {function} params.checker need more work on this one later - * @param {string} params.alias mostly for cmd - */ - var createConfig = function (value, type, params) { - if ( params === void 0 ) params = {}; - - // Note the enumv not ENUM - // const { enumv, optional, checker, alias } = params; - // let args = [value, type, optional, enumv, checker, alias]; - var o = params[OPTIONAL_KEY]; - var e = params[ENUM_KEY]; - var c = params[CHECKER_KEY]; - var a = params[ALIAS_KEY]; - return constructConfigFn.apply(null, [value, type, o, e, c, a]) - }; - - // copy of above but it's sync - var checkConfig = function(validateSync) { - return function(config, appProps, constantProps) { - if ( constantProps === void 0 ) constantProps = {}; - - return checkOptionsSync(config, appProps, constantProps, validateSync) - } - }; - - // export - // PIA syntax - var isObject$1 = checkIsObject; - var isString$1 = checkIsString; - - var createConfig$1 = createConfig; - var checkConfig$1 = checkConfig(validateSync); - - // bunch of generic helpers - - /** - * @param {boolean} sec return in second or not - * @return {number} timestamp - */ - var timestamp = function (sec) { - if ( sec === void 0 ) sec = false; - - var time = Date.now(); - return sec ? Math.floor( time / 1000 ) : time; - }; - - var lookup = []; - var revLookup = []; - var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; - var inited = false; - function init () { - inited = true; - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i]; - revLookup[code.charCodeAt(i)] = i; - } - - revLookup['-'.charCodeAt(0)] = 62; - revLookup['_'.charCodeAt(0)] = 63; - } - - function toByteArray (b64) { - if (!inited) { - init(); - } - var i, j, l, tmp, placeHolders, arr; - var len = b64.length; - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders); - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len; - - var L = 0; - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; - arr[L++] = (tmp >> 16) & 0xFF; - arr[L++] = (tmp >> 8) & 0xFF; - arr[L++] = tmp & 0xFF; - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); - arr[L++] = tmp & 0xFF; - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); - arr[L++] = (tmp >> 8) & 0xFF; - arr[L++] = tmp & 0xFF; - } - - return arr - } - - function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] - } - - function encodeChunk (uint8, start, end) { - var tmp; - var output = []; - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); - output.push(tripletToBase64(tmp)); - } - return output.join('') - } - - function fromByteArray (uint8) { - if (!inited) { - init(); - } - var tmp; - var len = uint8.length; - var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes - var output = ''; - var parts = []; - var maxChunkLength = 16383; // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1]; - output += lookup[tmp >> 2]; - output += lookup[(tmp << 4) & 0x3F]; - output += '=='; - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); - output += lookup[tmp >> 10]; - output += lookup[(tmp >> 4) & 0x3F]; - output += lookup[(tmp << 2) & 0x3F]; - output += '='; - } - - parts.push(output); - - return parts.join('') - } - - function read (buffer, offset, isLE, mLen, nBytes) { - var e, m; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var nBits = -7; - var i = isLE ? (nBytes - 1) : 0; - var d = isLE ? -1 : 1; - var s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) - } - - function write (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c; - var eLen = nBytes * 8 - mLen - 1; - var eMax = (1 << eLen) - 1; - var eBias = eMax >> 1; - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); - var i = isLE ? 0 : (nBytes - 1); - var d = isLE ? 1 : -1; - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128; - } - - var toString$1 = {}.toString; - - var isArray$1 = Array.isArray || function (arr) { - return toString$1.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$2.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined - ? global$1.TYPED_ARRAY_SUPPORT - : true; - - function kMaxLength () { - return Buffer$2.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff - } - - function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length); - that.__proto__ = Buffer$2.prototype; - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer$2(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$2 (arg, encodingOrOffset, length) { - if (!Buffer$2.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer$2)) { - return new Buffer$2(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$1(this, arg) - } - return from(this, arg, encodingOrOffset, length) - } - - Buffer$2.poolSize = 8192; // not used by this implementation - - // TODO: Legacy, not needed anymore. Remove in next major version. - Buffer$2._augment = function (arr) { - arr.__proto__ = Buffer$2.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$2.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) - }; - - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - Buffer$2.prototype.__proto__ = Uint8Array.prototype; - Buffer$2.__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$2.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) - }; - - function allocUnsafe$1 (that, size) { - assertSize(size); - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); - if (!Buffer$2.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$2.allocUnsafe = function (size) { - return allocUnsafe$1(null, size) - }; - /** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ - Buffer$2.allocUnsafeSlow = function (size) { - return allocUnsafe$1(null, size) - }; - - function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8'; - } - - if (!Buffer$2.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$2.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array; - that.__proto__ = Buffer$2.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$1(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$2.isBuffer = isBuffer$1; - function internalIsBuffer (b) { - return !!(b != null && b._isBuffer) - } - - Buffer$2.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$2.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$2.concat = function concat (list, length) { - if (!isArray$1(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer$2.alloc(0) - } - - var i; - if (length === undefined) { - length = 0; - for (i = 0; i < list.length; ++i) { - length += list[i].length; - } - } - - var buffer = Buffer$2.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$2.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$2.prototype._isBuffer = true; - - function swap (b, n, m) { - var i = b[n]; - b[n] = b[m]; - b[m] = i; - } - - Buffer$2.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$2.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$2.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$2.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$2.prototype.equals = function equals (b) { - if (!internalIsBuffer(b)) { throw new TypeError('Argument must be a Buffer') } - if (this === b) { return true } - return Buffer$2.compare(this, b) === 0 - }; - - Buffer$2.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$2.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$2.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$2.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$2.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 - }; - - Buffer$2.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) - }; - - Buffer$2.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$2.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$2.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$2.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$2.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end); - newBuf.__proto__ = Buffer$2.prototype; - } else { - var sliceLen = end - start; - newBuf = new Buffer$2(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$2.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$2.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$2.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 1, this.length); } - return this[offset] - }; - - Buffer$2.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return this[offset] | (this[offset + 1] << 8) - }; - - Buffer$2.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 2, this.length); } - return (this[offset] << 8) | this[offset + 1] - }; - - Buffer$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.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$2.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, true, 23, 4) - }; - - Buffer$2.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 4, this.length); } - return read(this, offset, false, 23, 4) - }; - - Buffer$2.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) { checkOffset(offset, 8, this.length); } - return read(this, offset, true, 52, 8) - }; - - Buffer$2.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$2.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$2.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$2.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0xff, 0); } - if (!Buffer$2.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$2.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 - }; - - Buffer$2.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0xffff, 0); } - if (Buffer$2.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$2.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer$2.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$2.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0xffffffff, 0); } - if (Buffer$2.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$2.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$2.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$2.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); } - if (!Buffer$2.TYPED_ARRAY_SUPPORT) { value = Math.floor(value); } - if (value < 0) { value = 0xff + value + 1; } - this[offset] = (value & 0xff); - return offset + 1 - }; - - Buffer$2.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff); - this[offset + 1] = (value >>> 8); - } else { - objectWriteUInt16(this, value, offset, true); - } - return offset + 2 - }; - - Buffer$2.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); } - if (Buffer$2.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8); - this[offset + 1] = (value & 0xff); - } else { - objectWriteUInt16(this, value, offset, false); - } - return offset + 2 - }; - - Buffer$2.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value; - offset = offset | 0; - if (!noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); } - if (Buffer$2.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$2.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$2.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$2.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) - }; - - Buffer$2.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$2.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) - }; - - Buffer$2.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) - }; - - // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) - Buffer$2.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$2.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$2.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$2.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$2(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$1(obj) { - return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) - } - - function isFastBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) - } - - // For Node v0.10 support. Remove this eventually. - function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) - } - - if (typeof global$1.setTimeout === 'function') ; - if (typeof global$1.clearTimeout === 'function') ; - - // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js - var performance = global$1.performance || {}; - var performanceNow = - performance.now || - performance.mozNow || - performance.msNow || - performance.oNow || - performance.webkitNow || - function(){ return (new Date()).getTime() }; - - // when the user is login with the jwt - /** - * We only check the nbf and exp - * @param {object} token for checking - * @return {object} token on success - */ - function validate(token) { - var start = token.iat || timestamp(); - // we only check the exp for the time being - if (token.exp) { - if (start >= token.exp) { - var expired = new Date(token.exp).toISOString(); - throw new JsonqlError(("Token has expired on " + expired), token) - } - } - return token; - } - - /** - * The browser client version it has far fewer options and it doesn't verify it - * because it couldn't this is the job for the server - * @TODO we need to add some extra proessing here to check for the exp field - * @param {string} token to decrypted - * @return {object} decrypted object - */ - function jwtDecode(token) { - if (isString$1(token)) { - var t = lib(token); - return validate(t) - } - throw new JsonqlError('Token must be a string!') - } - - var obj, obj$1, obj$2, obj$3, obj$4, obj$5, obj$6, obj$7, obj$8; - - var appProps = { - algorithm: createConfig$1(HSA_ALGO, [STRING_TYPE]), - expiresIn: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj = {}, obj[ALIAS_KEY] = 'exp', obj[OPTIONAL_KEY] = true, obj )), - notBefore: createConfig$1(false, [BOOLEAN_TYPE, NUMBER_TYPE, STRING_TYPE], ( obj$1 = {}, obj$1[ALIAS_KEY] = 'nbf', obj$1[OPTIONAL_KEY] = true, obj$1 )), - audience: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$2 = {}, obj$2[ALIAS_KEY] = 'iss', obj$2[OPTIONAL_KEY] = true, obj$2 )), - subject: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$3 = {}, obj$3[ALIAS_KEY] = 'sub', obj$3[OPTIONAL_KEY] = true, obj$3 )), - issuer: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$4 = {}, obj$4[ALIAS_KEY] = 'iss', obj$4[OPTIONAL_KEY] = true, obj$4 )), - noTimestamp: createConfig$1(false, [BOOLEAN_TYPE], ( obj$5 = {}, obj$5[OPTIONAL_KEY] = true, obj$5 )), - header: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$6 = {}, obj$6[OPTIONAL_KEY] = true, obj$6 )), - keyid: createConfig$1(false, [BOOLEAN_TYPE, STRING_TYPE], ( obj$7 = {}, obj$7[OPTIONAL_KEY] = true, obj$7 )), - mutatePayload: createConfig$1(false, [BOOLEAN_TYPE], ( obj$8 = {}, obj$8[OPTIONAL_KEY] = true, obj$8 )) - }; - - function tokenValidator(config) { - if (!isObject$1(config)) { - return {}; // we just ignore it all together? - } - var result = {}; - var opts = checkConfig$1(config, appProps); - // need to remove options that is false - for (var key in opts) { - if (opts[key]) { - result[key] = opts[key]; - } - } - return result; - } - - exports.decodeToken = jwtDecode; - exports.tokenValidator = tokenValidator; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); +!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})}); -- Gitee From ca9203e75b8811f1f09d1f6f7cb573b5354def93 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 14:59:53 +0100 Subject: [PATCH 43/59] add a todo method for config to type valdiation for Typescript next --- packages/validator/package.json | 2 +- packages/validator/src/props-to-interface.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/validator/src/props-to-interface.js diff --git a/packages/validator/package.json b/packages/validator/package.json index 4522e0ad..62842b50 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-params-validator", - "version": "1.4.5", + "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", diff --git a/packages/validator/src/props-to-interface.js b/packages/validator/src/props-to-interface.js new file mode 100644 index 00000000..4d3024d7 --- /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 +} -- Gitee From 7e5fc1b825eb7bfc70300159761ade0cb43c018b Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:04:33 +0100 Subject: [PATCH 44/59] reimport the jsonql-utils --- .../validator/dist/jsonql-params-validator.cjs.js | 2 -- .../validator/dist/jsonql-params-validator.cjs.js.map | 1 - .../validator/dist/jsonql-params-validator.umd.js | 2 -- .../validator/dist/jsonql-params-validator.umd.js.map | 1 - packages/validator/package.json | 1 + packages/validator/src/options/check-options-sync.js | 2 +- packages/validator/src/options/construct-config.js | 11 ++++++----- .../src/options/prepare-args-for-validation.js | 7 +++---- packages/validator/src/options/run-validation.js | 10 +++++----- 9 files changed, 16 insertions(+), 21 deletions(-) delete mode 100644 packages/validator/dist/jsonql-params-validator.cjs.js delete mode 100644 packages/validator/dist/jsonql-params-validator.cjs.js.map delete mode 100644 packages/validator/dist/jsonql-params-validator.umd.js delete mode 100644 packages/validator/dist/jsonql-params-validator.umd.js.map diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js b/packages/validator/dist/jsonql-params-validator.cjs.js deleted file mode 100644 index c4e50fb0..00000000 --- a/packages/validator/dist/jsonql-params-validator.cjs.js +++ /dev/null @@ -1,2 +0,0 @@ -"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; -//# 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 deleted file mode 100644 index 44a652f1..00000000 --- a/packages/validator/dist/jsonql-params-validator.cjs.js.map +++ /dev/null @@ -1 +0,0 @@ -{"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 diff --git a/packages/validator/dist/jsonql-params-validator.umd.js b/packages/validator/dist/jsonql-params-validator.umd.js deleted file mode 100644 index d71077f0..00000000 --- a/packages/validator/dist/jsonql-params-validator.umd.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t=t||self).jsonqlParamsValidator={})}(this,function(t){"use strict";var r="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n="object"==typeof r&&r&&r.Object===Object&&r,e="object"==typeof self&&self&&self.Object===Object&&self,o=n||e||Function("return this")(),u=o.Symbol,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})}); -//# 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 deleted file mode 100644 index ce1a9495..00000000 --- a/packages/validator/dist/jsonql-params-validator.umd.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"jsonql-params-validator.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/validator/package.json b/packages/validator/package.json index 62842b50..1dd9e70d 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -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": { diff --git a/packages/validator/src/options/check-options-sync.js b/packages/validator/src/options/check-options-sync.js index 9a569092..7e9efaa3 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 5810d8e9..6e0fb1f8 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 907eb4a4..389f76d8 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 31e96142..2709166e 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'; -- Gitee From 67abd7302a49d6dcf606c0e5417cfd504e88ffa3 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:10:53 +0100 Subject: [PATCH 45/59] resolve the problem with some of node import from utils but why its not doing tree shaking --- packages/validator/dist/jsonql-params-validator.cjs.js | 2 ++ packages/validator/dist/jsonql-params-validator.cjs.js.map | 1 + packages/validator/dist/jsonql-params-validator.umd.js | 2 ++ packages/validator/dist/jsonql-params-validator.umd.js.map | 1 + packages/validator/rollup.config.js | 5 ++++- 5 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 packages/validator/dist/jsonql-params-validator.cjs.js create mode 100644 packages/validator/dist/jsonql-params-validator.cjs.js.map create mode 100644 packages/validator/dist/jsonql-params-validator.umd.js create mode 100644 packages/validator/dist/jsonql-params-validator.umd.js.map diff --git a/packages/validator/dist/jsonql-params-validator.cjs.js b/packages/validator/dist/jsonql-params-validator.cjs.js new file mode 100644 index 00000000..8f5db377 --- /dev/null +++ b/packages/validator/dist/jsonql-params-validator.cjs.js @@ -0,0 +1,2 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("debug");var global$1="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},freeGlobal="object"==typeof global$1&&global$1&&global$1.Object===Object&&global$1,freeSelf="object"==typeof self&&self&&self.Object===Object&&self,root=freeGlobal||freeSelf||Function("return this")(),Symbol=root.Symbol,objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol?Symbol.toStringTag:void 0;function getRawTag(e){var r=hasOwnProperty.call(e,symToStringTag),t=e[symToStringTag];try{var n=!(e[symToStringTag]=void 0)}catch(e){}var o=nativeObjectToString.call(e);return n&&(r?e[symToStringTag]=t:delete e[symToStringTag]),o}var objectProto$1=Object.prototype,nativeObjectToString$1=objectProto$1.toString;function objectToString(e){return nativeObjectToString$1.call(e)}var nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag$1=Symbol?Symbol.toStringTag:void 0;function baseGetTag(e){return null==e?void 0===e?undefinedTag:nullTag:symToStringTag$1&&symToStringTag$1 in Object(e)?getRawTag(e):objectToString(e)}function isObjectLike(e){return null!=e&&"object"==typeof e}var symbolTag="[object Symbol]";function isSymbol(e){return"symbol"==typeof e||isObjectLike(e)&&baseGetTag(e)==symbolTag}function arrayMap(e,r){for(var t=-1,n=null==e?0:e.length,o=Array(n);++t=HOT_COUNT)return arguments[0]}else n=0;return t.apply(void 0,arguments)}}function constant(e){return function(){return e}}var defineProperty=function(){try{var e=getNative(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),baseSetToString=defineProperty?function(e,r){return defineProperty(e,"toString",{configurable:!0,enumerable:!1,value:constant(r),writable:!0})}:identity,setToString=shortOut(baseSetToString);function baseFindIndex(e,r,t,n){for(var o=e.length,a=t+(n?1:-1);n?a--:++a>>0,r>>>=0;for(var a=Array(o);++n",NO_STATUS_CODE=-1,ARGS_NOT_ARRAY_ERR="args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)",PARAMS_NOT_ARRAY_ERR="params is not an array! Did something gone wrong when you generate the contract.json?",EXCEPTION_CASE_ERR="Could not understand your arguments and parameter structure!",DEFAULT_TYPE$1=DEFAULT_TYPE,ARRAY_TYPE_LFT$1=ARRAY_TYPE_LFT,ARRAY_TYPE_RGT$1=ARRAY_TYPE_RGT,TYPE_KEY$1=TYPE_KEY,OPTIONAL_KEY$1=OPTIONAL_KEY,ENUM_KEY$1=ENUM_KEY,ARGS_KEY$1=ARGS_KEY,CHECKER_KEY$1=CHECKER_KEY,ALIAS_KEY$1=ALIAS_KEY,ARRAY_TYPE$1=ARRAY_TYPE,OBJECT_TYPE$1=OBJECT_TYPE,STRING_TYPE$1=STRING_TYPE,BOOLEAN_TYPE$1=BOOLEAN_TYPE,NUMBER_TYPE$1=NUMBER_TYPE,KEY_WORD$1=KEY_WORD,OR_SEPERATOR$1=OR_SEPERATOR,combineFn=function(e){switch(e){case NUMBER_TYPE$1:return checkIsNumber;case STRING_TYPE$1:return checkIsString;case BOOLEAN_TYPE$1:return checkIsBoolean;default:return checkIsAny}},checkIsArray=function(e,r){return void 0===r&&(r=""),!!isArray(e)&&(""===r||""===trim(r)||!(0t.filter(function(e){return!combineFn(e)(r)}).length)}).length:t.length>t.filter(function(e){return!checkIsArray(r,e)}).length},checkIsObject=function(r,e){if(void 0===e&&(e=null),isPlainObject(r)){if(!e)return!0;if(checkIsArray(e))return!e.filter(function(e){var t=r[e.name];return!(e.type.length>e.type.filter(function(e){var r;return!!isUndefined(t)||(!1!==(r=isArrayLike$1(e))?!arrayTypeHandler({arg:t},r):!combineFn(e)(t))}).length)}).length}return!1},objectTypeHandler=function(e){var r=e.arg,t=e.param,n=[r];return Array.isArray(t.keys)&&t.keys.length&&n.push(t.keys),checkIsObject.apply(null,n)},isBrowser=function(){try{if(window||document)return!0}catch(e){}return!1},isNode=function(){try{if(!isBrowser()&&global$1)return!0}catch(e){}return!1};function whereAmI(){return isBrowser()?"browser":isNode()?"node":"unknown"}var JsonqlBaseError=function(t){function e(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e)}return t&&(e.__proto__=t),((e.prototype=Object.create(t&&t.prototype)).constructor=e).where=function(){return whereAmI()},e}(Error),JsonqlEnumError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(n,e),n}(Error),JsonqlTypeError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(n,e),n}(Error),JsonqlCheckerError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,t.captureStackTrace&&t.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0}};return e.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(n,e),n}(Error),JsonqlError=function(t){function n(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];t.apply(this,e),this.message=e[0],this.detail=e[1],this.className=n.name,Error.captureStackTrace&&Error.captureStackTrace(this,n)}t&&(n.__proto__=t),(n.prototype=Object.create(t&&t.prototype)).constructor=n;var e={name:{configurable:!0},statusCode:{configurable:!0}};return e.name.get=function(){return"JsonqlError"},e.statusCode.get=function(){return NO_STATUS_CODE},Object.defineProperties(n,e),n}(JsonqlBaseError);function log(){for(var e=[],r=arguments.length;r--;)e[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,e)}catch(e){}}var optionalHandler=function(r){var e=r.arg,t=r.param;return!!notEmpty(e)&&!(t.type.length>t.type.filter(function(e){return validateHandler(e,r)}).length)},validateHandler=function(e,r){var t;switch(!0){case e===OBJECT_TYPE$1:return!objectTypeHandler(r);case e===ARRAY_TYPE$1:return!checkIsArray(r.arg);case!1!==(t=isArrayLike$1(e)):return!arrayTypeHandler(r,t);default:return!combineFn(e)(r.arg)}},getOptionalValue=function(e,r){return isUndefined(e)?!0!==r.optional||isUndefined(r.defaultvalue)?null:r.defaultvalue:e},normalizeArgs=function(t,o){if(!checkIsArray(o))throw new JsonqlError(PARAMS_NOT_ARRAY_ERR);if(0===o.length)return[];if(!checkIsArray(t))throw new JsonqlError(ARGS_NOT_ARRAY_ERR);switch(!0){case t.length==o.length:return log(1),t.map(function(e,r){return{arg:e,index:r,param:o[r]}});case!0===o[0].variable:log(2);var n=o[0].type;return t.map(function(e,r){return{arg:e,index:r,param:o[r]||{type:n,name:"_"}}});case t.lengtho.length:log(4);var a=o.length,i=[DEFAULT_TYPE$1];return t.map(function(e,r){var t=a<=r||!!o[r].optional,n=o[r]||{type:i,name:"_"+r};return{arg:t?getOptionalValue(e,n):e,index:r,param:n,optional:t}});default:throw log(5),new JsonqlError(EXCEPTION_CASE_ERR,{args:t,params:o})}},processReturn=function(e){return e.map(function(e){return e.arg})},validateSync=function(e,r,t){var n;void 0===t&&(t=!1);var o=normalizeArgs(e,r),a=o.filter(function(r){return!0===r.optional||!0===r.param.optional?optionalHandler(r):!(r.param.type.length>r.param.type.filter(function(e){return validateHandler(e,r)}).length)});return t?((n={})[ERROR_KEY]=a,n[DATA_KEY]=processReturn(o),n):a},validateAsync=function(n,o,a){return void 0===a&&(a=!1),new Promise(function(e,r){var t=validateSync(n,o,a);return a?t[ERROR_KEY].length?r(t[ERROR_KEY]):e(t[DATA_KEY]):t.length?r(t):e([])})},inArray=function(e,r){return!!e.filter(function(e){return e===r}).length},isKeyInObject=function(e,r){var t=Object.keys(e);return inArray(t,r)},lookup=[],revLookup=[],Arr="undefined"!=typeof Uint8Array?Uint8Array:Array,inited=!1;function init(){inited=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,t=e.length;r>16&255,a[s++]=n>>8&255,a[s++]=255&n;return 2==o?(n=revLookup[e.charCodeAt(r)]<<2|revLookup[e.charCodeAt(r+1)]>>4,a[s++]=255&n):1==o&&(n=revLookup[e.charCodeAt(r)]<<10|revLookup[e.charCodeAt(r+1)]<<4|revLookup[e.charCodeAt(r+2)]>>2,a[s++]=n>>8&255,a[s++]=255&n),a}function tripletToBase64(e){return lookup[e>>18&63]+lookup[e>>12&63]+lookup[e>>6&63]+lookup[63&e]}function encodeChunk(e,r,t){for(var n,o=[],a=r;a>2],o+=lookup[r<<4&63],o+="=="):2==n&&(r=(e[t-2]<<8)+e[t-1],o+=lookup[r>>10],o+=lookup[r>>4&63],o+=lookup[r<<2&63],o+="="),a.push(o),a.join("")}function read(e,r,t,n,o){var a,i,s=8*o-n-1,u=(1<>1,c=-7,l=t?o-1:0,h=t?-1:1,p=e[r+l];for(l+=h,a=p&(1<<-c)-1,p>>=-c,c+=s;0>=-c,c+=n;0>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:a-1,g=n?1:-1,y=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(s=isNaN(r)?1:0,i=c):(i=Math.floor(Math.log(r)/Math.LN2),r*(u=Math.pow(2,-i))<1&&(i--,u*=2),2<=(r+=1<=i+l?h/u:h*Math.pow(2,1-l))*u&&(i++,u/=2),c<=i+l?(s=0,i=c):1<=i+l?(s=(r*u-1)*Math.pow(2,o),i+=l):(s=r*Math.pow(2,l-1)*Math.pow(2,o),i=0));8<=o;e[t+p]=255&s,p+=g,s/=256,o-=8);for(i=i<=kMaxLength())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength().toString(16)+" bytes");return 0|e}function internalIsBuffer(e){return!(null==e||!e._isBuffer)}function byteLength(e,r){if(internalIsBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var t=e.length;if(0===t)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return t;case"utf8":case"utf-8":case void 0:return utf8ToBytes(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*t;case"hex":return t>>>1;case"base64":return base64ToBytes(e).length;default:if(n)return utf8ToBytes(e).length;r=(""+r).toLowerCase(),n=!0}}function slowToString(e,r,t){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===t||t>this.length)&&(t=this.length),t<=0)return"";if((t>>>=0)<=(r>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return hexSlice(this,r,t);case"utf8":case"utf-8":return utf8Slice(this,r,t);case"ascii":return asciiSlice(this,r,t);case"latin1":case"binary":return latin1Slice(this,r,t);case"base64":return base64Slice(this,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,r,t);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function swap(e,r,t){var n=e[r];e[r]=e[t],e[t]=n}function bidirectionalIndexOf(e,r,t,n,o){if(0===e.length)return-1;if("string"==typeof t?(n=t,t=0):2147483647=e.length){if(o)return-1;t=e.length-1}else if(t<0){if(!o)return-1;t=0}if("string"==typeof r&&(r=Buffer$2.from(r,n)),internalIsBuffer(r))return 0===r.length?-1:arrayIndexOf(e,r,t,n,o);if("number"==typeof r)return r&=255,Buffer$2.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,r,t):Uint8Array.prototype.lastIndexOf.call(e,r,t):arrayIndexOf(e,[r],t,n,o);throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(e,r,t,n,o){var a,i=1,s=e.length,u=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||r.length<2)return-1;s/=i=2,u/=2,t/=2}function f(e,r){return 1===i?e[r]:e.readUInt16BE(r*i)}if(o){var c=-1;for(a=t;a>>10&1023|55296),c=56320|1023&c),n.push(c),o+=l}return decodeCodePointsArray(n)}Buffer$2.TYPED_ARRAY_SUPPORT=void 0===global$1.TYPED_ARRAY_SUPPORT||global$1.TYPED_ARRAY_SUPPORT,Buffer$2.poolSize=8192,Buffer$2._augment=function(e){return e.__proto__=Buffer$2.prototype,e},Buffer$2.from=function(e,r,t){return from(null,e,r,t)},Buffer$2.TYPED_ARRAY_SUPPORT&&(Buffer$2.prototype.__proto__=Uint8Array.prototype,Buffer$2.__proto__=Uint8Array),Buffer$2.alloc=function(e,r,t){return alloc(null,e,r,t)},Buffer$2.allocUnsafe=function(e){return allocUnsafe$1(null,e)},Buffer$2.allocUnsafeSlow=function(e){return allocUnsafe$1(null,e)},Buffer$2.isBuffer=isBuffer$1,Buffer$2.compare=function(e,r){if(!internalIsBuffer(e)||!internalIsBuffer(r))throw new TypeError("Arguments must be Buffers");if(e===r)return 0;for(var t=e.length,n=r.length,o=0,a=Math.min(t,n);or&&(e+=" ... ")),""},Buffer$2.prototype.compare=function(e,r,t,n,o){if(!internalIsBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===t&&(t=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),r<0||t>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(o<=n&&t<=r)return 0;if(o<=n)return-1;if(t<=r)return 1;if(this===e)return 0;for(var a=(o>>>=0)-(n>>>=0),i=(t>>>=0)-(r>>>=0),s=Math.min(a,i),u=this.slice(n,o),f=e.slice(r,t),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n=n||"utf8";for(var a=!1;;)switch(n){case"hex":return hexWrite(this,e,r,t);case"utf8":case"utf-8":return utf8Write(this,e,r,t);case"ascii":return asciiWrite(this,e,r,t);case"latin1":case"binary":return latin1Write(this,e,r,t);case"base64":return base64Write(this,e,r,t);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,e,r,t);default:if(a)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),a=!0}},Buffer$2.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(e){var r=e.length;if(r<=MAX_ARGUMENTS_LENGTH)return String.fromCharCode.apply(String,e);for(var t="",n=0;ne.length)throw new RangeError("Index out of range")}function objectWriteUInt16(e,r,t,n){r<0&&(r=65535+r+1);for(var o=0,a=Math.min(e.length-t,2);o>>8*(n?o:1-o)}function objectWriteUInt32(e,r,t,n){r<0&&(r=4294967295+r+1);for(var o=0,a=Math.min(e.length-t,4);o>>8*(n?o:3-o)&255}function checkIEEE754(e,r,t,n,o,a){if(t+n>e.length)throw new RangeError("Index out of range");if(t<0)throw new RangeError("Index out of range")}function writeFloat(e,r,t,n,o){return o||checkIEEE754(e,r,t,4),write(e,r,t,n,23,4),t+4}function writeDouble(e,r,t,n,o){return o||checkIEEE754(e,r,t,8),write(e,r,t,n,52,8),t+8}Buffer$2.prototype.slice=function(e,r){var t,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeUInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,65535,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeUInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r+3]=e>>>24,this[r+2]=e>>>16,this[r+1]=e>>>8,this[r]=255&e):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeUInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,4294967295,0),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeIntLE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=0,i=1,s=0;for(this[r]=255&e;++a>0)-s&255;return r+t},Buffer$2.prototype.writeIntBE=function(e,r,t,n){if(e=+e,r|=0,!n){var o=Math.pow(2,8*t-1);checkInt(this,e,r,t,o-1,-o)}var a=t-1,i=1,s=0;for(this[r+a]=255&e;0<=--a&&(i*=256);)e<0&&0===s&&0!==this[r+a+1]&&(s=1),this[r+a]=(e/i>>0)-s&255;return r+t},Buffer$2.prototype.writeInt8=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,1,127,-128),Buffer$2.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[r]=255&e,r+1},Buffer$2.prototype.writeInt16LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8):objectWriteUInt16(this,e,r,!0),r+2},Buffer$2.prototype.writeInt16BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,2,32767,-32768),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>8,this[r+1]=255&e):objectWriteUInt16(this,e,r,!1),r+2},Buffer$2.prototype.writeInt32LE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=255&e,this[r+1]=e>>>8,this[r+2]=e>>>16,this[r+3]=e>>>24):objectWriteUInt32(this,e,r,!0),r+4},Buffer$2.prototype.writeInt32BE=function(e,r,t){return e=+e,r|=0,t||checkInt(this,e,r,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Buffer$2.TYPED_ARRAY_SUPPORT?(this[r]=e>>>24,this[r+1]=e>>>16,this[r+2]=e>>>8,this[r+3]=255&e):objectWriteUInt32(this,e,r,!1),r+4},Buffer$2.prototype.writeFloatLE=function(e,r,t){return writeFloat(this,e,r,!0,t)},Buffer$2.prototype.writeFloatBE=function(e,r,t){return writeFloat(this,e,r,!1,t)},Buffer$2.prototype.writeDoubleLE=function(e,r,t){return writeDouble(this,e,r,!0,t)},Buffer$2.prototype.writeDoubleBE=function(e,r,t){return writeDouble(this,e,r,!1,t)},Buffer$2.prototype.copy=function(e,r,t,n){if(t=t||0,n||0===n||(n=this.length),r>=e.length&&(r=e.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-r>>=0,t=void 0===t?this.length:t>>>0,"number"==typeof(e=e||0))for(a=r;a>6|192,63&t|128)}else if(t<65536){if((r-=3)<0)break;a.push(t>>12|224,t>>6&63|128,63&t|128)}else{if(!(t<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;a.push(t>>18|240,t>>12&63|128,t>>6&63|128,63&t|128)}}return a}function asciiToBytes(e){for(var r=[],t=0;t>8,o=t%256,a.push(o),a.push(n);return a}function base64ToBytes(e){return toByteArray(base64clean(e))}function blitBuffer(e,r,t,n){for(var o=0;o=r.length||o>=e.length);++o)r[o+t]=e[o];return o}function isnan(e){return e!=e}function isBuffer$1(e){return null!=e&&(!!e._isBuffer||isFastBuffer(e)||isSlowBuffer(e))}function isFastBuffer(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function isSlowBuffer(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&isFastBuffer(e.slice(0,0))}global$1.setTimeout,global$1.clearTimeout;var performance=global$1.performance||{},performanceNow=performance.now||performance.mozNow||performance.msNow||performance.oNow||performance.webkitNow||function(){return(new Date).getTime()},isEmpty=function(e){return!notEmpty(e)};function mapAliasConfigKeys(e,r){var t=omitBy(r,function(e,r){return!e[ALIAS_KEY$1]});return isEqual(t,{})?e:mapKeys(e,function(e,r){return findKey(t,function(e){return e.alias===r})||r})}function preservePristineValues(e,r){var t=mapAliasConfigKeys(e,r);return{pristineValues:mapValues(omitBy(r,function(e,r){return isKeyInObject(t,r)}),function(e){return e.args}),checkAgainstAppProps:omitBy(r,function(e,r){return!isKeyInObject(t,r)}),config:t}}function processConfigAction(o,e){return mapValues(e,function(e,r){var t,n;return isUndefined(o[r])||!0===e[OPTIONAL_KEY$1]&&isEmpty(o[r])?merge({},e,((t={})[KEY_WORD$1]=!0,t)):((n={})[ARGS_KEY$1]=o[r],n[TYPE_KEY$1]=e[TYPE_KEY$1],n[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1]||!1,n[ENUM_KEY$1]=e[ENUM_KEY$1]||!1,n[CHECKER_KEY$1]=e[CHECKER_KEY$1]||!1,n)})}function prepareArgsForValidation(e,r){var t=preservePristineValues(e,r),n=t.config,o=t.pristineValues;return[processConfigAction(n,t.checkAgainstAppProps),o]}var toArray=function(e){return checkIsArray(e)?e:[e]},inArray$1=function(e,r){return!!e.filter(function(e){return e===r}).length};function validateHandler$1(e,r){var t,n=[[e[ARGS_KEY$1]],[(t={},t[TYPE_KEY$1]=toArray(e[TYPE_KEY$1]),t[OPTIONAL_KEY$1]=e[OPTIONAL_KEY$1],t)]];return Reflect.apply(r,null,n)}var enumHandler=function(e,r){return!checkIsArray(r)||inArray$1(r,e)},checkerHandler=function(e,r){try{return!!isFunction(r)&&r.apply(null,[e])}catch(e){return!1}};function runValidationAction(n){return function(e,r){if(e[KEY_WORD$1])return e[ARGS_KEY$1];var t=validateHandler$1(e,n);if(t.length)throw log("runValidationAction",r,e),new JsonqlTypeError(r,t);if(!1!==e[ENUM_KEY$1]&&!enumHandler(e[ARGS_KEY$1],e[ENUM_KEY$1]))throw log(ENUM_KEY$1,e[ENUM_KEY$1]),new JsonqlEnumError(r);if(!1!==e[CHECKER_KEY$1]&&!checkerHandler(e[ARGS_KEY$1],e[CHECKER_KEY$1]))throw log(CHECKER_KEY$1,e[CHECKER_KEY$1]),new JsonqlCheckerError(r);return e[ARGS_KEY$1]}}function runValidation(e,r){var t=e[0],n=e[1],o=mapValues(t,runValidationAction(r));return merge(o,n)}var configToArgs=function(e,r){return Promise.resolve(prepareArgsForValidation(e,r))};function checkOptionsAsync(e,r,t,n){return void 0===e&&(e={}),configToArgs(e,r).then(function(e){return runValidation(e,n)}).then(function(e){return merge({},e,t)})}function checkOptionsSync(e,r,t,n){return void 0===e&&(e={}),merge(runValidation(prepareArgsForValidation(e,r),n),t)}function constructConfigFn(e,r,t,n,o,a){void 0===t&&(t=!1),void 0===n&&(n=!1),void 0===o&&(o=!1),void 0===a&&(a=!1);var i={};return i[ARGS_KEY]=e,i[TYPE_KEY]=r,!0===t&&(i[OPTIONAL_KEY]=!0),checkIsArray(n)&&(i[ENUM_KEY]=n),isFunction(o)&&(i[CHECKER_KEY]=o),isString(a)&&(i[ALIAS_KEY]=a),i}var createConfig=function(e,r,t){void 0===t&&(t={});var n=t[OPTIONAL_KEY],o=t[ENUM_KEY],a=t[CHECKER_KEY],i=t[ALIAS_KEY];return constructConfigFn.apply(null,[e,r,n,o,a,i])},JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.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 new file mode 100644 index 00000000..29f1ab1a --- /dev/null +++ b/packages/validator/dist/jsonql-params-validator.cjs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"jsonql-params-validator.cjs.js","sources":["../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/buffer-es6/isArray.js"],"sourcesContent":["export default (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n","var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"qFAAA,2tvCCAA"} \ No newline at end of file diff --git a/packages/validator/dist/jsonql-params-validator.umd.js b/packages/validator/dist/jsonql-params-validator.umd.js new file mode 100644 index 00000000..44e996a0 --- /dev/null +++ b/packages/validator/dist/jsonql-params-validator.umd.js @@ -0,0 +1,2 @@ +!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("debug")):"function"==typeof define&&define.amd?define(["exports","debug"],r):r((t=t||self).jsonqlParamsValidator={},t.debug)}(this,function(t,r){"use strict";r=r&&r.hasOwnProperty("default")?r.default:r;var n="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e="object"==typeof n&&n&&n.Object===Object&&n,o="object"==typeof self&&self&&self.Object===Object&&self,i=e||o||Function("return this")(),u=i.Symbol,a=Object.prototype,f=a.hasOwnProperty,c=a.toString,s=u?u.toStringTag:void 0;var h=Object.prototype.toString;var l="[object Null]",p="[object Undefined]",g=u?u.toStringTag:void 0;function v(t){return null==t?void 0===t?p:l:g&&g in Object(t)?function(t){var r=f.call(t,s),n=t[s];try{var e=!(t[s]=void 0)}catch(t){}var o=c.call(t);return e&&(r?t[s]=n:delete t[s]),o}(t):function(t){return h.call(t)}(t)}function y(t){return null!=t&&"object"==typeof t}var d="[object Symbol]";function b(t){return"symbol"==typeof t||y(t)&&v(t)==d}function w(t,r){for(var n=-1,e=null==t?0:t.length,o=Array(e);++n>>0,r>>>=0;for(var i=Array(o);++e")){var r=t.replace(Ne,"").replace(">","");return r.indexOf("|")?r.split("|"):[r]}return!1}function ke(t,n){var r=t.arg;return 1n.filter(function(t){return!Ue(t)(r)}).length)}).length:n.length>n.filter(function(t){return!Be(r,t)}).length}function Ye(r,t){if(void 0===t&&(t=null),Ar(r)){if(!t)return!0;if(Be(t))return!t.filter(function(t){var n=r[t.name];return!(t.type.length>t.type.filter(function(t){var r;return!!ve(n)||(!1!==(r=Ie(t))?!ke({arg:n},r):!Ue(t)(n))}).length)}).length}return!1}function Ce(){try{if(window||document)return!0}catch(t){}return!1}var xe="error",Me="optional",Le="enumv",ze="checker",De="alias",Ne="array.<",Fe="type",Ve=Me,$e=Le,qe="args",Je=ze,We=De,Ge="continue";function Qe(){return Ce()?"browser":function(){try{if(!Ce()&&n)return!0}catch(t){}return!1}()?"node":"unknown"}var Ze=function(n){function t(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t)}return n&&(t.__proto__=n),((t.prototype=Object.create(n&&n.prototype)).constructor=t).where=function(){return Qe()},t}(Error),He=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlEnumError"},Object.defineProperties(e,t),e}(Error),Ke=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlTypeError"},Object.defineProperties(e,t),e}(Error),Xe=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,n.captureStackTrace&&n.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0}};return t.name.get=function(){return"JsonqlCheckerError"},Object.defineProperties(e,t),e}(Error),to=function(n){function e(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];n.apply(this,t),this.message=t[0],this.detail=t[1],this.className=e.name,Error.captureStackTrace&&Error.captureStackTrace(this,e)}n&&(e.__proto__=n),(e.prototype=Object.create(n&&n.prototype)).constructor=e;var t={name:{configurable:!0},statusCode:{configurable:!0}};return t.name.get=function(){return"JsonqlError"},t.statusCode.get=function(){return-1},Object.defineProperties(e,t),e}(Ze);function ro(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];try{window&&window.debug&&Reflect.apply(console.log,console,t)}catch(t){}}function no(t,r){return ve(t)?!0!==r.optional||ve(r.defaultvalue)?null:r.defaultvalue:t}function eo(n,o){if(!Be(o))throw new to("params is not an array! Did something gone wrong when you generate the contract.json?");if(0===o.length)return[];if(!Be(n))throw new to("args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)");switch(!0){case n.length==o.length:return ro(1),n.map(function(t,r){return{arg:t,index:r,param:o[r]}});case!0===o[0].variable:ro(2);var e=o[0].type;return n.map(function(t,r){return{arg:t,index:r,param:o[r]||{type:e,name:"_"}}});case n.lengtho.length:ro(4);var i=o.length,u=["any"];return n.map(function(t,r){var n=i<=r||!!o[r].optional,e=o[r]||{type:u,name:"_"+r};return{arg:n?no(t,e):t,index:r,param:e,optional:n}});default:throw ro(5),new to("Could not understand your arguments and parameter structure!",{args:n,params:o})}}function oo(t,r,n){var e;void 0===n&&(n=!1);var o=eo(t,r),i=o.filter(function(r){return!0===r.optional||!0===r.param.optional?function(r){var t=r.arg,n=r.param;return!!Oe(t)&&!(n.type.length>n.type.filter(function(t){return io(t,r)}).length)}(r):!(r.param.type.length>r.param.type.filter(function(t){return io(t,r)}).length)});return n?((e={})[xe]=i,e.data=function(t){return t.map(function(t){return t.arg})}(o),e):i}var io=function(t,r){var n;switch(!0){case"object"===t:return!function(t){var r=t.arg,n=t.param,e=[r];return Array.isArray(n.keys)&&n.keys.length&&e.push(n.keys),Ye.apply(null,e)}(r);case"array"===t:return!Be(r.arg);case!1!==(n=Ie(t)):return!ke(r,n);default:return!Ue(t)(r.arg)}},uo=function(t,r){return function(t,r){return!!t.filter(function(t){return t===r}).length}(Object.keys(t),r)},ao=[],fo=[],co="undefined"!=typeof Uint8Array?Uint8Array:Array,so=!1;function ho(){so=!0;for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r=0,n=t.length;r>18&63]+ao[o>>12&63]+ao[o>>6&63]+ao[63&o]);return i.join("")}function po(t){var r;so||ho();for(var n=t.length,e=n%3,o="",i=[],u=0,a=n-e;u>2],o+=ao[r<<4&63],o+="=="):2==e&&(r=(t[n-2]<<8)+t[n-1],o+=ao[r>>10],o+=ao[r>>4&63],o+=ao[r<<2&63],o+="="),i.push(o),i.join("")}function go(t,r,n,e,o){var i,u,a=8*o-e-1,f=(1<>1,s=-7,h=n?o-1:0,l=n?-1:1,p=t[r+h];for(h+=l,i=p&(1<<-s)-1,p>>=-s,s+=a;0>=-s,s+=e;0>1,l=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=e?0:i-1,g=e?1:-1,v=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,u=s):(u=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-u))<1&&(u--,f*=2),2<=(r+=1<=u+h?l/f:l*Math.pow(2,1-h))*f&&(u++,f/=2),s<=u+h?(a=0,u=s):1<=u+h?(a=(r*f-1)*Math.pow(2,o),u+=h):(a=r*Math.pow(2,h-1)*Math.pow(2,o),u=0));8<=o;t[n+p]=255&a,p+=g,a/=256,o-=8);for(u=u<=wo())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+wo().toString(16)+" bytes");return 0|t}function Ro(t){return!(null==t||!t._isBuffer)}function To(t,r){if(Ro(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var e=!1;;)switch(r){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return Zo(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return Ho(t).length;default:if(e)return Zo(t).length;r=(""+r).toLowerCase(),e=!0}}function So(t,r,n){var e=t[r];t[r]=t[n],t[n]=e}function Uo(t,r,n,e,o){if(0===t.length)return-1;if("string"==typeof n?(e=n,n=0):2147483647=t.length){if(o)return-1;n=t.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof r&&(r=mo.from(r,e)),Ro(r))return 0===r.length?-1:Bo(t,r,n,e,o);if("number"==typeof r)return r&=255,mo.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,r,n):Uint8Array.prototype.lastIndexOf.call(t,r,n):Bo(t,[r],n,e,o);throw new TypeError("val must be string, number or Buffer")}function Bo(t,r,n,e,o){var i,u=1,a=t.length,f=r.length;if(void 0!==e&&("ucs2"===(e=String(e).toLowerCase())||"ucs-2"===e||"utf16le"===e||"utf-16le"===e)){if(t.length<2||r.length<2)return-1;a/=u=2,f/=2,n/=2}function c(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(o){var s=-1;for(i=n;i>>10&1023|55296),s=56320|1023&s),e.push(s),o+=h}return function(t){var r=t.length;if(r<=xo)return String.fromCharCode.apply(String,t);var n="",e=0;for(;ethis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(r>>>=0))return"";for(t=t||"utf8";;)switch(t){case"hex":return zo(this,r,n);case"utf8":case"utf-8":return Co(this,r,n);case"ascii":return Mo(this,r,n);case"latin1":case"binary":return Lo(this,r,n);case"base64":return Yo(this,r,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Do(this,r,n);default:if(e)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),e=!0}}.apply(this,arguments)},mo.prototype.equals=function(t){if(!Ro(t))throw new TypeError("Argument must be a Buffer");return this===t||0===mo.compare(this,t)},mo.prototype.inspect=function(){var t="";return 0"},mo.prototype.compare=function(t,r,n,e,o){if(!Ro(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===n&&(n=t?t.length:0),void 0===e&&(e=0),void 0===o&&(o=this.length),r<0||n>t.length||e<0||o>this.length)throw new RangeError("out of range index");if(o<=e&&n<=r)return 0;if(o<=e)return-1;if(n<=r)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(e>>>=0),u=(n>>>=0)-(r>>>=0),a=Math.min(i,u),f=this.slice(e,o),c=t.slice(r,n),s=0;sthis.length)throw new RangeError("Attempt to write outside buffer bounds");e=e||"utf8";for(var i,u,a,f,c,s,h,l,p,g=!1;;)switch(e){case"hex":return Io(this,t,r,n);case"utf8":case"utf-8":return l=r,p=n,Ko(Zo(t,(h=this).length-l),h,l,p);case"ascii":return ko(this,t,r,n);case"latin1":case"binary":return ko(this,t,r,n);case"base64":return f=this,c=r,s=n,Ko(Ho(t),f,c,s);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return u=r,a=n,Ko(function(t,r){for(var n,e,o,i=[],u=0;u>8,o=n%256,i.push(o),i.push(e);return i}(t,(i=this).length-u),i,u,a);default:if(g)throw new TypeError("Unknown encoding: "+e);e=(""+e).toLowerCase(),g=!0}},mo.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var xo=4096;function Mo(t,r,n){var e="";n=Math.min(t.length,n);for(var o=r;ot.length)throw new RangeError("Index out of range")}function Vo(t,r,n,e){r<0&&(r=65535+r+1);for(var o=0,i=Math.min(t.length-n,2);o>>8*(e?o:1-o)}function $o(t,r,n,e){r<0&&(r=4294967295+r+1);for(var o=0,i=Math.min(t.length-n,4);o>>8*(e?o:3-o)&255}function qo(t,r,n,e){if(n+e>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function Jo(t,r,n,e,o){return o||qo(t,0,n,4),vo(t,r,n,e,23,4),n+4}function Wo(t,r,n,e,o){return o||qo(t,0,n,8),vo(t,r,n,e,52,8),n+8}mo.prototype.slice=function(t,r){var n,e=this.length;if((t=~~t)<0?(t+=e)<0&&(t=0):e>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeUInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,65535,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeUInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):$o(this,t,r,!0),r+4},mo.prototype.writeUInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,4294967295,0),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeIntLE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=0,u=1,a=0;for(this[r]=255&t;++i>0)-a&255;return r+n},mo.prototype.writeIntBE=function(t,r,n,e){if(t=+t,r|=0,!e){var o=Math.pow(2,8*n-1);Fo(this,t,r,n,o-1,-o)}var i=n-1,u=1,a=0;for(this[r+i]=255&t;0<=--i&&(u*=256);)t<0&&0===a&&0!==this[r+i+1]&&(a=1),this[r+i]=(t/u>>0)-a&255;return r+n},mo.prototype.writeInt8=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,1,127,-128),mo.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},mo.prototype.writeInt16LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):Vo(this,t,r,!0),r+2},mo.prototype.writeInt16BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,2,32767,-32768),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):Vo(this,t,r,!1),r+2},mo.prototype.writeInt32LE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),mo.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):$o(this,t,r,!0),r+4},mo.prototype.writeInt32BE=function(t,r,n){return t=+t,r|=0,n||Fo(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),mo.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):$o(this,t,r,!1),r+4},mo.prototype.writeFloatLE=function(t,r,n){return Jo(this,t,r,!0,n)},mo.prototype.writeFloatBE=function(t,r,n){return Jo(this,t,r,!1,n)},mo.prototype.writeDoubleLE=function(t,r,n){return Wo(this,t,r,!0,n)},mo.prototype.writeDoubleBE=function(t,r,n){return Wo(this,t,r,!1,n)},mo.prototype.copy=function(t,r,n,e){if(n=n||0,e||0===e||(e=this.length),r>=t.length&&(r=t.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(e<0)throw new RangeError("sourceEnd out of bounds");e>this.length&&(e=this.length),t.length-r>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(t=t||0))for(i=r;i>6|192,63&n|128)}else if(n<65536){if((r-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function Ho(t){return function(t){var r,n,e,o,i;so||ho();var u=t.length;if(0>16&255,i[a++]=e>>8&255,i[a++]=255&e;return 2==o?(e=fo[t.charCodeAt(r)]<<2|fo[t.charCodeAt(r+1)]>>4,i[a++]=255&e):1==o&&(e=fo[t.charCodeAt(r)]<<10|fo[t.charCodeAt(r+1)]<<4|fo[t.charCodeAt(r+2)]>>2,i[a++]=e>>8&255,i[a++]=255&e),i}(function(t){if((t=function(t){if(t.trim)return t.trim();return t.replace(/^\s+|\s+$/g,"")}(t).replace(Go,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Ko(t,r,n,e){for(var o=0;o=r.length||o>=t.length);++o)r[o+n]=t[o];return o}function Xo(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}n.setTimeout,n.clearTimeout;var ti=n.performance||{},ri=(ti.now||ti.mozNow||ti.msNow||ti.oNow||ti.webkitNow,function(t){return!Oe(t)});function ni(t,r){var n=Ae(r,function(t,r){return!t[We]});return function(t,r){return $n(t,r)}(n,{})?t:function(t,e){var o={};return e=ne(e),ie(t,function(t,r,n){ut(o,e(t,r,n),t)}),o}(t,function(t,r){return function(t,r){return function(t,e,r){var o;return r(t,function(t,r,n){if(e(t,r,n))return o=r,!1}),o}(t,ne(r),ie)}(n,function(t){return t.alias===r})||r})}function ei(t,r){var n=function(t,r){var n=ni(t,r);return{pristineValues:ye(Ae(r,function(t,r){return uo(n,r)}),function(t){return t.args}),checkAgainstAppProps:Ae(r,function(t,r){return!uo(n,r)}),config:n}}(t,r),e=n.config,o=n.pristineValues;return[function(o,t){return ye(t,function(t,r){var n,e;return ve(o[r])||!0===t[Ve]&&ri(o[r])?be({},t,((n={})[Ge]=!0,n)):((e={})[qe]=o[r],e[Fe]=t[Fe],e[Ve]=t[Ve]||!1,e[$e]=t[$e]||!1,e[Je]=t[Je]||!1,e)})}(e,n.checkAgainstAppProps),o]}var oi=function(t){return Be(t)?t:[t]};var ii=function(t,r){return!Be(r)||function(t,r){return!!t.filter(function(t){return t===r}).length}(r,t)},ui=function(t,r){try{return!!B(r)&&r.apply(null,[t])}catch(t){return!1}};function ai(e){return function(t,r){if(t[Ge])return t[qe];var n=function(t,r){var n,e=[[t[qe]],[(n={},n[Fe]=oi(t[Fe]),n[Ve]=t[Ve],n)]];return Reflect.apply(r,null,e)}(t,e);if(n.length)throw ro("runValidationAction",r,t),new Ke(r,n);if(!1!==t[$e]&&!ii(t[qe],t[$e]))throw ro($e,t[$e]),new He(r);if(!1!==t[Je]&&!ui(t[qe],t[Je]))throw ro(Je,t[Je]),new Xe(r);return t[qe]}}function fi(t,r){var n=t[0],e=t[1],o=ye(n,ai(r));return be(o,e)}function ci(t,r,n,e){return void 0===t&&(t={}),function(t,r){return Promise.resolve(ei(t,r))}(t,r).then(function(t){return fi(t,e)}).then(function(t){return be({},t,n)})}function si(t,r,n,e,o,i){void 0===n&&(n=!1),void 0===e&&(e=!1),void 0===o&&(o=!1),void 0===i&&(i=!1);var u={};return u.args=t,u.type=r,!0===n&&(u[Me]=!0),Be(e)&&(u[Le]=e),B(o)&&(u[ze]=o),le(i)&&(u[De]=i),u}function hi(e,o,i){return void 0===i&&(i=!1),new Promise(function(t,r){var n=oo(e,o,i);return i?n[xe].length?r(n[xe]):t(n.data):n.length?r(n):t([])})}function li(t,r,n){void 0===n&&(n={});var e=n[Me],o=n[Le],i=n[ze],u=n[De];return si.apply(null,[t,r,e,o,i,u])}var pi,gi,vi=Ye,yi=Se,di=Re,bi=Te,wi=Pe,_i=Be,mi=Oe,Ai=eo,ji=oo,Ei=si,Oi=(pi=oo,function(t,r,n){return void 0===n&&(n={}),ci(t,r,n,pi)}),Pi=(gi=oo,function(t,r,n){return void 0===n&&(n={}),function(t,r,n,e){return void 0===t&&(t={}),be(fi(ei(t,r),e),n)}(t,r,n,gi)});t.JSONQL_PARAMS_VALIDATOR_INFO="version: 1.4.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 new file mode 100644 index 00000000..07b453b6 --- /dev/null +++ b/packages/validator/dist/jsonql-params-validator.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"jsonql-params-validator.umd.js","sources":["../node_modules/buffer-es6/isArray.js"],"sourcesContent":["var toString = {}.toString;\n\nexport default Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n"],"names":[],"mappings":"sn2BAAA"} \ No newline at end of file diff --git a/packages/validator/rollup.config.js b/packages/validator/rollup.config.js index 2ed2ef40..34e3df32 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: [ -- Gitee From 697447535024050e452331dc91748678557f9838 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:15:44 +0100 Subject: [PATCH 46/59] move part of test to the jsonql-utils --- packages/utils/tests/construct.test.js | 21 +++++++++++++++++++ .../validator/tests/construct-config.test.js | 20 ------------------ 2 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 packages/utils/tests/construct.test.js diff --git a/packages/utils/tests/construct.test.js b/packages/utils/tests/construct.test.js new file mode 100644 index 00000000..998a0367 --- /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/validator/tests/construct-config.test.js b/packages/validator/tests/construct-config.test.js index b048fcb6..b1c90c2d 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')) - -}) -- Gitee From a7c2cf94d9dbcd7d61797b92828c55af2b4b980d Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:23:58 +0100 Subject: [PATCH 47/59] all ported test passed --- packages/utils/package.json | 5 +- packages/utils/src/contract.js | 6 +- packages/utils/tests/client-utils.test.js | 1 - packages/utils/tests/fixtures/contract.json | 111 ++++++++++++++++++++ 4 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 packages/utils/tests/fixtures/contract.json diff --git a/packages/utils/package.json b/packages/utils/package.json index 9948d9a6..e8aeb883 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.14", + "version": "0.3.15", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", @@ -55,6 +55,7 @@ "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/contract.js b/packages/utils/src/contract.js index ae710e3f..593139a6 100644 --- a/packages/utils/src/contract.js +++ b/packages/utils/src/contract.js @@ -44,13 +44,17 @@ export 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 function groupByNamespace(contract) { +export function groupByNamespace(contract, fallback = false) { let socket = extractSocketPart(contract) if (socket === false) { + if (fallback) { + return contract; // just return the whole contract + } throw new JsonqlError(`socket not found in contract!`) } let nspSet = {}; diff --git a/packages/utils/tests/client-utils.test.js b/packages/utils/tests/client-utils.test.js index 6113ea9f..41191823 100644 --- a/packages/utils/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/fixtures/contract.json b/packages/utils/tests/fixtures/contract.json new file mode 100644 index 00000000..72510498 --- /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" + } + ] + } + } +} -- Gitee From 573a9e165148b5e520999ac70d4fe3bc668b6533 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:39:00 +0100 Subject: [PATCH 48/59] start moving other utils over --- packages/utils/es.js | 1 + packages/utils/package.json | 2 +- packages/utils/src/generic.js | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/utils/es.js b/packages/utils/es.js index 25e2c335..d4f45cbe 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -13,6 +13,7 @@ import { replaceErrors, printError } from './src/error' import { getDebug, inArray, + toArray, isKeyInObject, injectToFn, createEvt, diff --git a/packages/utils/package.json b/packages/utils/package.json index e8aeb883..cfbabce8 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.3.15", + "version": "0.4.0", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 053d48c2..8584418b 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -1,6 +1,6 @@ // 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 : @@ -18,6 +18,9 @@ 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 +const toArray = (arg) => isArray(arg) ? arg : [arg]; + /** * @param {object} obj for search * @param {string} key target -- Gitee From a07b2b1dd9b9ab7461291bdbcaa929af248d7f2d Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:39:43 +0100 Subject: [PATCH 49/59] jsonql-utils to 0.4.0 --- packages/utils/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index cfbabce8..f62bf674 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -10,7 +10,8 @@ "src" ], "scripts": { - "test": "ava", + "test": "ava --verbose", + "prepare": "npm run test", "test:params": "DEBUG=jsonql* ava ./tests/params-api.test.js" }, "keywords": [ -- Gitee From ea4df06040a71afdf8ecf2468c3ace0b479a97e7 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 15:41:47 +0100 Subject: [PATCH 50/59] fix the toArray export --- packages/utils/src/generic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/src/generic.js b/packages/utils/src/generic.js index 8584418b..0201c98f 100644 --- a/packages/utils/src/generic.js +++ b/packages/utils/src/generic.js @@ -19,7 +19,7 @@ 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 -const toArray = (arg) => isArray(arg) ? arg : [arg]; +export const toArray = (arg) => isArray(arg) ? arg : [arg]; /** * @param {object} obj for search -- Gitee From 24e0401ed94b954de2c4144e0b26e9dc669f4ab5 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 22:51:42 +0100 Subject: [PATCH 51/59] redesign the constants and moving socket lib specific files out and keep jsonql-ws-client as helper library only --- .../socketio}/src/io/create-client.js | 2 -- .../socketio}/src/io/index.js | 0 .../socketio}/src/io/io-main-handler.js | 0 .../socketio/src}/socketio-clients.js | 0 packages/constants/{main.js => module.js} | 1 + packages/constants/package.json | 16 ++++++++-------- packages/ws-client/README.md | 17 +++++++---------- packages/ws-client/package.json | 2 +- 8 files changed, 17 insertions(+), 21 deletions(-) rename packages/{ws-client => @jsonql/socketio}/src/io/create-client.js (99%) rename packages/{ws-client => @jsonql/socketio}/src/io/index.js (100%) rename packages/{ws-client => @jsonql/socketio}/src/io/io-main-handler.js (100%) rename packages/{ws-client/src/node => @jsonql/socketio/src}/socketio-clients.js (100%) rename packages/constants/{main.js => module.js} (99%) 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 a8986f5d..8c4c8ae2 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/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/constants/main.js b/packages/constants/module.js similarity index 99% rename from packages/constants/main.js rename to packages/constants/module.js index e68b2023..f147e753 100644 --- a/packages/constants/main.js +++ b/packages/constants/module.js @@ -133,6 +133,7 @@ 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 diff --git a/packages/constants/package.json b/packages/constants/package.json index c3eaa227..a45f205d 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/ws-client/README.md b/packages/ws-client/README.md index fa9299d8..982f95df 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/package.json b/packages/ws-client/package.json index 37d20f87..67084a33 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", + "description": "This is the web socket client helper library", "main": "main.js", "module": "index.js", "browser": "dist/jsonql-ws-client.js", -- Gitee From 70646b212ab7cd001bd02f2a1d393baafc31448a Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 23:27:16 +0100 Subject: [PATCH 52/59] jsonql-constants to v1.8.1 with reduce deps and new build script --- packages/constants/README.md | 181 +++++++++++++++++--------- packages/constants/README_TEMPLATE.md | 19 +++ packages/constants/build.js | 29 +++-- packages/constants/constants.json | 1 + packages/constants/index.js | 2 +- packages/constants/main.js | 176 +++++++++++++++++++++++++ 6 files changed, 340 insertions(+), 68 deletions(-) create mode 100644 packages/constants/README_TEMPLATE.md create mode 100644 packages/constants/main.js diff --git a/packages/constants/README.md b/packages/constants/README.md index 1bf09ed8..0d01a6b9 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 00000000..82b1e764 --- /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 f98d22bf..6e01805d 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 520eabba..bc04e319 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 8dfc9adf..fbb92340 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 new file mode 100644 index 00000000..dab22c3e --- /dev/null +++ b/packages/constants/main.js @@ -0,0 +1,176 @@ +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 -- Gitee From d8448151a7fc6d4c4503a90a2fb7c1b0e1d353fa Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 23:28:38 +0100 Subject: [PATCH 53/59] move ws files into @jsonql/ws --- packages/{ws-client/src/node => @jsonql/ws/src}/ws-client.js | 0 packages/{ws-client => @jsonql/ws}/src/ws/create-client.js | 0 packages/{ws-client => @jsonql/ws}/src/ws/extract-ws-payload.js | 0 packages/{ws-client => @jsonql/ws}/src/ws/index.js | 0 packages/{ws-client => @jsonql/ws}/src/ws/ws-main-handler.js | 0 packages/{ws-client => @jsonql/ws}/src/ws/ws.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename packages/{ws-client/src/node => @jsonql/ws/src}/ws-client.js (100%) rename packages/{ws-client => @jsonql/ws}/src/ws/create-client.js (100%) rename packages/{ws-client => @jsonql/ws}/src/ws/extract-ws-payload.js (100%) rename packages/{ws-client => @jsonql/ws}/src/ws/index.js (100%) rename packages/{ws-client => @jsonql/ws}/src/ws/ws-main-handler.js (100%) rename packages/{ws-client => @jsonql/ws}/src/ws/ws.js (100%) 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 -- Gitee From 90c74eadbba3a49df6cf53848d03bf186dcd6428 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 23:36:35 +0100 Subject: [PATCH 54/59] add new objDefineProps method for use with the jsonql-ws-client and other place that provide setter and geeter to object --- packages/utils/es.js | 5 ++++- packages/utils/package.json | 2 +- packages/utils/src/obj-define-props.js | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 packages/utils/src/obj-define-props.js diff --git a/packages/utils/es.js b/packages/utils/es.js index d4f45cbe..efc4dba4 100644 --- a/packages/utils/es.js +++ b/packages/utils/es.js @@ -54,6 +54,7 @@ import { getNameFromPayload } from './src/params-api' import { buff } from './src/jwt' +import { objDefineProps } from './src/obj-define-props' // alias const isContract = checkIsContract; // exports @@ -111,5 +112,7 @@ export { getMutationFromPayload, getNameFromPayload, // node - buff + buff, + // objectDefineProp + objDefineProps } diff --git a/packages/utils/package.json b/packages/utils/package.json index f62bf674..13ea4b34 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-utils", - "version": "0.4.0", + "version": "0.4.1", "description": "This is a jsonql dependency module, not for generate use.", "main": "main.js", "module": "es.js", diff --git a/packages/utils/src/obj-define-props.js b/packages/utils/src/obj-define-props.js new file mode 100644 index 00000000..1fb0783a --- /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 +} -- Gitee From 771ca668e0996d3c5d89ce95afffe9987144b040 Mon Sep 17 00:00:00 2001 From: joelchu Date: Wed, 4 Sep 2019 23:46:12 +0100 Subject: [PATCH 55/59] just marking the ideas --- packages/ws-client/package.json | 9 ++++----- packages/ws-client/src/create-socket-client.js | 14 ++++++++++---- packages/ws-client/src/node/client-generator.js | 4 ++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/ws-client/package.json b/packages/ws-client/package.json index 67084a33..cc137281 100755 --- a/packages/ws-client/package.json +++ b/packages/ws-client/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-client", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.3", "description": "This is the web socket client helper library", "main": "main.js", "module": "index.js", @@ -47,7 +47,6 @@ "license": "MIT", "devDependencies": { "ava": "^2.2.0", - "esm": "^3.2.25", "fs-extra": "^8.1.0", "glob": "^7.1.4", "jsonql-contract": "^1.7.7", @@ -72,7 +71,8 @@ "rollup-pluginutils": "^2.8.1", "server-io-core": "^1.2.0", "sorcery": "^0.10.0", - "ws": "^7.1.2" + "ws": "^7.1.2", + "kefir": "^3.8.6" }, "ava": { "files": [ @@ -95,12 +95,11 @@ "node": ">=8" }, "dependencies": { - "debug": "^4.1.1", + "esm": "^3.2.25", "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", "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 08429459..60b4df6c 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 48edb54b..788a3153 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 -- Gitee From 17cc776d838cac4f9b245411a8fbe2d7fea11c86 Mon Sep 17 00:00:00 2001 From: joelchu Date: Thu, 5 Sep 2019 09:44:59 +0100 Subject: [PATCH 56/59] moving the scripts over to their respective new owners --- packages/@jsonql/socketio/package.json | 69 +++++++++++++++++++++++++- packages/@jsonql/ws/package.json | 64 +++++++++++++++++++++++- packages/ws-client/index.js | 5 +- packages/ws-client/main.js | 8 +-- packages/ws-client/package.json | 24 ++------- 5 files changed, 139 insertions(+), 31 deletions(-) diff --git a/packages/@jsonql/socketio/package.json b/packages/@jsonql/socketio/package.json index 033d269f..e67109ee 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/@jsonql/ws/package.json b/packages/@jsonql/ws/package.json index b431434a..1e56c46c 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/ws-client/index.js b/packages/ws-client/index.js index 934b4c00..ca4dec95 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 d8bb48a4..fbb92340 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 cc137281..001dc41c 100755 --- a/packages/ws-client/package.json +++ b/packages/ws-client/package.json @@ -12,24 +12,9 @@ "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,7 +26,8 @@ "jsonql", "socket.io", "ws", - "Web Socket" + "Web Socket", + "primus" ], "author": "Joel Chu ", "license": "MIT", -- Gitee From d1b529e5f04a03c29b536a432a66f0b5f4e1fb1e Mon Sep 17 00:00:00 2001 From: joelchu Date: Thu, 5 Sep 2019 09:46:49 +0100 Subject: [PATCH 57/59] move the test over --- .../tests/browser/files/simple-test.js | 25 + .../socketio/tests/browser/run-qunit.js | 98 +++ .../socketio/tests/browser/webroot/index.html | 107 +++ .../tests/browser/webroot/qunit-log.js | 29 + .../tests/fixtures/contract-config-auth.js | 10 + .../tests/fixtures/contract-config.js | 9 + .../fixtures/contract/auth/contract.json | 111 +++ .../contract/auth/public-contract.json | 117 +++ .../tests/fixtures/contract/contract.json | 84 ++ .../fixtures/contract/public-contract.json | 91 +++ .../socketio/tests/fixtures/io-setup.js | 23 + .../tests/fixtures/keys/privateKey.pem | 15 + .../tests/fixtures/keys/publicKey.pem | 6 + .../socketio/tests/fixtures/node/index.js | 8 + .../socketio/tests/fixtures/node/test.cjs.js | 720 ++++++++++++++++++ .../socketio/tests/fixtures/node/test.js | 16 + .../fixtures/resolvers/socket/continuous.js | 21 + .../resolvers/socket/public/pinging.js | 22 + .../resolvers/socket/send-extra-msg.js | 12 + .../tests/fixtures/resolvers/socket/simple.js | 9 + .../fixtures/resolvers/socket/throw-error.js | 9 + .../socketio/tests/fixtures/server-setup.js | 37 + .../@jsonql/socketio/tests/fixtures/token.js | 16 + .../tests/io-chain-connection.test.js | 49 ++ .../tests/io-client-hs-auth-login.test.js | 81 ++ .../socketio/tests/io-client-hs-auth.test.js | 70 ++ .../tests/io-client-rt-auth-login.test.js | 95 +++ .../socketio/tests/io-client-rt-auth.test.js | 61 ++ .../@jsonql/socketio/tests/io-client.test.js | 76 ++ .../jwt/socketio-chain-connect-hs.test.js | 86 +++ .../jwt/socketio-chain-connect-rt.test.js | 51 ++ .../tests/jwt/socketio-handshake.test.js | 133 ++++ .../tests/jwt/socketio-roundtrip-fail.test.js | 60 ++ .../tests/jwt/socketio-roundtrip.test.js | 119 +++ .../socketio/tests/jwt/ws-handshake.test.js | 104 +++ .../@jsonql/socketio/tests/test-node.test.js | 204 +++++ .../ws/tests/browser/files/simple-test.js | 25 + .../@jsonql/ws/tests/browser/run-qunit.js | 98 +++ .../ws/tests/browser/webroot/index.html | 107 +++ .../ws/tests/browser/webroot/qunit-log.js | 29 + .../ws/tests/fixtures/contract-config-auth.js | 10 + .../ws/tests/fixtures/contract-config.js | 9 + .../fixtures/contract/auth/contract.json | 111 +++ .../contract/auth/public-contract.json | 117 +++ .../ws/tests/fixtures/contract/contract.json | 84 ++ .../fixtures/contract/public-contract.json | 91 +++ .../@jsonql/ws/tests/fixtures/io-setup.js | 23 + .../ws/tests/fixtures/keys/privateKey.pem | 15 + .../ws/tests/fixtures/keys/publicKey.pem | 6 + .../@jsonql/ws/tests/fixtures/node/index.js | 8 + .../ws/tests/fixtures/node/test.cjs.js | 720 ++++++++++++++++++ .../@jsonql/ws/tests/fixtures/node/test.js | 16 + .../fixtures/resolvers/socket/continuous.js | 21 + .../resolvers/socket/public/pinging.js | 22 + .../resolvers/socket/send-extra-msg.js | 12 + .../tests/fixtures/resolvers/socket/simple.js | 9 + .../fixtures/resolvers/socket/throw-error.js | 9 + .../@jsonql/ws/tests/fixtures/server-setup.js | 37 + packages/@jsonql/ws/tests/fixtures/token.js | 16 + .../jwt/socketio-chain-connect-hs.test.js | 86 +++ .../jwt/socketio-chain-connect-rt.test.js | 51 ++ .../ws/tests/jwt/socketio-handshake.test.js | 133 ++++ .../tests/jwt/socketio-roundtrip-fail.test.js | 60 ++ .../ws/tests/jwt/socketio-roundtrip.test.js | 119 +++ .../@jsonql/ws/tests/jwt/ws-handshake.test.js | 104 +++ packages/@jsonql/ws/tests/test-node.test.js | 204 +++++ .../ws/tests/ws-client-auth-login.test.js | 103 +++ .../@jsonql/ws/tests/ws-client-auth.test.js | 94 +++ .../@jsonql/ws/tests/ws-client-chain.test.js | 99 +++ packages/@jsonql/ws/tests/ws-client.test.js | 83 ++ 70 files changed, 5515 insertions(+) create mode 100644 packages/@jsonql/socketio/tests/browser/files/simple-test.js create mode 100644 packages/@jsonql/socketio/tests/browser/run-qunit.js create mode 100644 packages/@jsonql/socketio/tests/browser/webroot/index.html create mode 100644 packages/@jsonql/socketio/tests/browser/webroot/qunit-log.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract-config-auth.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract-config.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract/auth/contract.json create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract/auth/public-contract.json create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract/contract.json create mode 100644 packages/@jsonql/socketio/tests/fixtures/contract/public-contract.json create mode 100644 packages/@jsonql/socketio/tests/fixtures/io-setup.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/keys/privateKey.pem create mode 100644 packages/@jsonql/socketio/tests/fixtures/keys/publicKey.pem create mode 100644 packages/@jsonql/socketio/tests/fixtures/node/index.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/node/test.cjs.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/node/test.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/resolvers/socket/continuous.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/resolvers/socket/public/pinging.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/resolvers/socket/send-extra-msg.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/resolvers/socket/simple.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/resolvers/socket/throw-error.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/server-setup.js create mode 100644 packages/@jsonql/socketio/tests/fixtures/token.js create mode 100644 packages/@jsonql/socketio/tests/io-chain-connection.test.js create mode 100644 packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js create mode 100644 packages/@jsonql/socketio/tests/io-client-hs-auth.test.js create mode 100644 packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js create mode 100644 packages/@jsonql/socketio/tests/io-client-rt-auth.test.js create mode 100644 packages/@jsonql/socketio/tests/io-client.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js create mode 100644 packages/@jsonql/socketio/tests/jwt/ws-handshake.test.js create mode 100644 packages/@jsonql/socketio/tests/test-node.test.js create mode 100644 packages/@jsonql/ws/tests/browser/files/simple-test.js create mode 100644 packages/@jsonql/ws/tests/browser/run-qunit.js create mode 100644 packages/@jsonql/ws/tests/browser/webroot/index.html create mode 100644 packages/@jsonql/ws/tests/browser/webroot/qunit-log.js create mode 100644 packages/@jsonql/ws/tests/fixtures/contract-config-auth.js create mode 100644 packages/@jsonql/ws/tests/fixtures/contract-config.js create mode 100644 packages/@jsonql/ws/tests/fixtures/contract/auth/contract.json create mode 100644 packages/@jsonql/ws/tests/fixtures/contract/auth/public-contract.json create mode 100644 packages/@jsonql/ws/tests/fixtures/contract/contract.json create mode 100644 packages/@jsonql/ws/tests/fixtures/contract/public-contract.json create mode 100644 packages/@jsonql/ws/tests/fixtures/io-setup.js create mode 100644 packages/@jsonql/ws/tests/fixtures/keys/privateKey.pem create mode 100644 packages/@jsonql/ws/tests/fixtures/keys/publicKey.pem create mode 100644 packages/@jsonql/ws/tests/fixtures/node/index.js create mode 100644 packages/@jsonql/ws/tests/fixtures/node/test.cjs.js create mode 100644 packages/@jsonql/ws/tests/fixtures/node/test.js create mode 100644 packages/@jsonql/ws/tests/fixtures/resolvers/socket/continuous.js create mode 100644 packages/@jsonql/ws/tests/fixtures/resolvers/socket/public/pinging.js create mode 100644 packages/@jsonql/ws/tests/fixtures/resolvers/socket/send-extra-msg.js create mode 100644 packages/@jsonql/ws/tests/fixtures/resolvers/socket/simple.js create mode 100644 packages/@jsonql/ws/tests/fixtures/resolvers/socket/throw-error.js create mode 100644 packages/@jsonql/ws/tests/fixtures/server-setup.js create mode 100644 packages/@jsonql/ws/tests/fixtures/token.js create mode 100644 packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js create mode 100644 packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js create mode 100644 packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js create mode 100644 packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js create mode 100644 packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js create mode 100644 packages/@jsonql/ws/tests/jwt/ws-handshake.test.js create mode 100644 packages/@jsonql/ws/tests/test-node.test.js create mode 100644 packages/@jsonql/ws/tests/ws-client-auth-login.test.js create mode 100644 packages/@jsonql/ws/tests/ws-client-auth.test.js create mode 100644 packages/@jsonql/ws/tests/ws-client-chain.test.js create mode 100644 packages/@jsonql/ws/tests/ws-client.test.js diff --git a/packages/@jsonql/socketio/tests/browser/files/simple-test.js b/packages/@jsonql/socketio/tests/browser/files/simple-test.js new file mode 100644 index 00000000..24f733c3 --- /dev/null +++ b/packages/@jsonql/socketio/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/socketio/tests/browser/run-qunit.js b/packages/@jsonql/socketio/tests/browser/run-qunit.js new file mode 100644 index 00000000..5fe81471 --- /dev/null +++ b/packages/@jsonql/socketio/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/socketio/tests/browser/webroot/index.html b/packages/@jsonql/socketio/tests/browser/webroot/index.html new file mode 100644 index 00000000..4f4f45ec --- /dev/null +++ b/packages/@jsonql/socketio/tests/browser/webroot/index.html @@ -0,0 +1,107 @@ + + + + + + QUnit testing for jsonql-client + + + + +
+
+ + + + + + + + + + diff --git a/packages/@jsonql/socketio/tests/browser/webroot/qunit-log.js b/packages/@jsonql/socketio/tests/browser/webroot/qunit-log.js new file mode 100644 index 00000000..9af483ab --- /dev/null +++ b/packages/@jsonql/socketio/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/socketio/tests/fixtures/contract-config-auth.js b/packages/@jsonql/socketio/tests/fixtures/contract-config-auth.js new file mode 100644 index 00000000..25fd9e0d --- /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 00000000..2187de94 --- /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 00000000..72510498 --- /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 00000000..62d35ef6 --- /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 00000000..3728746d --- /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 00000000..43cfd2b3 --- /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 00000000..65f37ec3 --- /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 00000000..52ceae92 --- /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 00000000..7bd2532a --- /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 00000000..3d6f0446 --- /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 00000000..0a8cb3e8 --- /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 00000000..d2387616 --- /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 00000000..3d468bb9 --- /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 00000000..2cf07351 --- /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 00000000..9144b99a --- /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 00000000..61810eae --- /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 00000000..a7fcd6f4 --- /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 00000000..1bb5ef2b --- /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 00000000..b1d44443 --- /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/@jsonql/socketio/tests/io-chain-connection.test.js b/packages/@jsonql/socketio/tests/io-chain-connection.test.js new file mode 100644 index 00000000..59569346 --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-chain-connection.test.js @@ -0,0 +1,49 @@ +// We need to make sure the private nsps connected and establish connection +// before we call the next client, otherwise it will break the auth connection +const test = require('ava') +const debug = require('debug')('jsonql-ws-client:test:io-chain-connection') +const { chainPromises } = require('jsonql-jwt') +// const chainCreateNsps = require('../src/io/chain-create-nsps') + +test('just testing the different between concat and push', t => { + let baseArr = [] + + let result = baseArr.push(1,2,3) + + debug(result) + + t.is(3, baseArr.length) + +}) + + +test('Test concat array without concat', t => { + const args = [1,2,3] + const newArgs = [4, ...args] + t.is(4, newArgs.length) + + const anotherNewArr = [5, ...Array(4,3,2,1)] + + debug(newArgs, anotherNewArr) +}) + +test.cb('It should able to run the array of promise one after another', t => { + t.plan(1) + let ps = [] + for (let i = 0; i < 2; ++i) { + ps.push( + new Promise(resolver => { + setTimeout(() => { + resolver(i+1) + }, 500) + }) + ) + } + // this is transform by esm on the fly so we got that annoying default key again + chainPromises(ps) + .then(result => { + debug(result) + t.pass() + t.end() + }) +}) diff --git a/packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js b/packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js new file mode 100644 index 00000000..4e2f23bf --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-client-hs-auth-login.test.js @@ -0,0 +1,81 @@ +// standard ws client test without auth +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') +const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') + +const wsClient = require('../main') +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 keysDir = join(__dirname, 'fixtures', 'keys') + +const debug = require('debug')('jsonql-ws-client:test:io-hs-login') + +const port = 8008; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + keysDir, + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: true + }) + + t.context.server = app.listen(port) + + t.context.client = await wsClient({ + serverType: JS_WS_SOCKET_IO_NAME, + hostname: `ws://localhost:${port}`, + contract: publicContract, + enableAuth: true, + useJwt: true + }) +}) + +test.after(t => { + t.context.server.close() +}) + +test.serial.cb('It should able to connect to the socket.io server public namespace', t => { + t.plan(1) + let client = t.context.client; + client.pinging('Hello') + client.pinging.onResult = (res) => { + debug('res', res) + t.is(res, 'connection established') + t.end() + } +}) +// this is confirm fucked becasue of the socket.io bug +// https://github.com/auth0-community/socketio-jwt/issues/95 +test.serial.cb('It should able to call the login method and establish socket.io connection using handshake', t => { + t.plan(1) + let client = t.context.client; + const payload = {name: 'Joel'} + const token = genToken(payload) + client.login(token) + // add onReady and wait for the login to happen + client.onReady = function(namespace) { + debug('--> onReady', namespace, client.sendExtraMsg.myNamespace) + if (namespace === client.sendExtraMsg.myNamespace) { + client.sendExtraMsg(200) + client.sendExtraMsg.onResult = (result) => { + debug('login success', result) + t.is(201, result) + t.end() + } + // this should work + // but this will happen before the above Promise.resolve + client.sendExtraMsg.onMessage = function(result) { + debug('onMessge got news', result) + } + } + } +}) diff --git a/packages/@jsonql/socketio/tests/io-client-hs-auth.test.js b/packages/@jsonql/socketio/tests/io-client-hs-auth.test.js new file mode 100644 index 00000000..90f38ca5 --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-client-hs-auth.test.js @@ -0,0 +1,70 @@ +// standard ws client test without auth +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') +const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') +const debug = require('debug')('jsonql-ws-client:test:io-hs') + +const wsClient = require('../main') +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 keysDir = join(__dirname, 'fixtures', 'keys') + +const { + chainPromises, + socketIoNodeHandshakeLogin, + socketIoNodeClientAsync +} = require('jsonql-jwt') + +const payload = {name: 'Joel'} +const token = genToken(payload) +const port = 8007; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + keysDir, + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: true + }) + + t.context.server = app.listen(port) + /* + t.context.client = await wsClient({ + token, + serverType: JS_WS_SOCKET_IO_NAME, + hostname: `ws://localhost:${port}`, + contract: publicContract, + enableAuth: true, + useJwt: true + }) + */ + +}) + +test.after(t => { + t.context.server.close() +}) + +test.cb('Just testing the chainPromises method with socket.io round trip login method', t => { + t.plan(1) + + let baseUrl = `ws://localhost:${port}/jsonql` + let nsp1url = [baseUrl, 'private'].join('/') + let nsp2url = [baseUrl, 'public'].join('/') + + let p1 = () => socketIoNodeHandshakeLogin(nsp1url, token) + let p2 = () => socketIoNodeClientAsync(nsp2url) + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length, 2) + t.end() + }) +}) diff --git a/packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js b/packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js new file mode 100644 index 00000000..e87f56ae --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-client-rt-auth-login.test.js @@ -0,0 +1,95 @@ +// standard ws client test without auth +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') +const { JS_WS_SOCKET_IO_NAME, IO_ROUNDTRIP_LOGIN } = require('jsonql-constants') +const debug = require('debug')('jsonql-ws-client:test:io-rt-login') + +const wsClient = require('../main') +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 keysDir = join(__dirname, 'fixtures', 'keys') +const secret = '123456789'; +const port = 8006; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + keysDir, + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: secret // <-- this is the secret + }) + + t.context.server = app.listen(port) + + t.context.client = await wsClient({ + serverType: JS_WS_SOCKET_IO_NAME, + hostname: `ws://localhost:${port}`, + contract: publicContract, + enableAuth: true, + useJwt: IO_ROUNDTRIP_LOGIN // <-- DON'T PASS THE SERVER SECRET! + }) +}) + +test.after(t => { + t.context.server.close() +}) + + +test.serial.cb('It should able to connect to the socket.io server public namespace', t => { + t.plan(1) + let client = t.context.client; + client.pinging('Hello') + client.pinging.onResult = (res) => { + debug('res', res) + t.is(res, 'connection established') + t.end() + } +}) + +test.serial.cb.skip('It should not able to connect to the socket.io private namespace at this point', t => { + t.plan(1) + let client = t.context.client; + client.sendExtraMsg(100) + // @TODO this one need to take a look at + client.sendExtraMsg.onError = error => { + debug('NOT_LOGIN_ERR_MSG', NOT_LOGIN_ERR_MSG, error.message) + t.is(NOT_LOGIN_ERR_MSG, error.message) + t.end() + } +}) + +test.serial.cb('It should able to call the login method and establish socket.io connection using the round trip method', t => { + t.plan(1) + let client = t.context.client; + const payload = {name: 'Joel'} + const token = genToken(payload, secret) + debug('call login', token) + + client.login(token) + + // add onReady and wait for the login to happen + + client.onReady = function(namespace) { + debug('--> onReady', namespace) + if (namespace === 'jsonql/private') { + client.sendExtraMsg(200) + client.sendExtraMsg.onResult = (result) => { + debug('login success', result) + t.is(201, result) + t.end() + } + // this should work + // but this will happen before the above Promise.resolve + client.sendExtraMsg.onMessage = function(result) { + debug('onMessge got news', result) + } + } + } +}) diff --git a/packages/@jsonql/socketio/tests/io-client-rt-auth.test.js b/packages/@jsonql/socketio/tests/io-client-rt-auth.test.js new file mode 100644 index 00000000..7ceff8fd --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-client-rt-auth.test.js @@ -0,0 +1,61 @@ +// standard ws client test without auth +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') +const { JS_WS_SOCKET_IO_NAME, IO_ROUNDTRIP_LOGIN } = require('jsonql-constants') +const debug = require('debug')('jsonql-ws-client:test:io-rt') + +const wsClient = require('../main') +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 keysDir = join(__dirname, 'fixtures', 'keys') + +const { + chainPromises, + socketIoNodeRoundtripLogin, + socketIoNodeClientAsync +} = require('jsonql-jwt') + +const secret = '12345678'; +const payload = {name: 'Joel'} +const token = genToken(payload, secret) + +const port = 8005; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + keysDir, + serverType: JS_WS_SOCKET_IO_NAME, + enableAuth: true, + useJwt: secret // <-- this is the secret + }) + + t.context.server = app.listen(port) +}) + +test.after(t => { + t.context.server.close() +}) + +test.cb('Just testing the chainPromises method with socket.io round trip login method', t => { + t.plan(1) + + let baseUrl = `ws://localhost:${port}/jsonql` + let nsp1url = [baseUrl, 'private'].join('/') + let nsp2url = [baseUrl, 'public'].join('/') + + let p1 = () => socketIoNodeRoundtripLogin(nsp1url, token) + let p2 = () => socketIoNodeClientAsync(nsp2url) + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length, 2) + t.end() + }) +}) diff --git a/packages/@jsonql/socketio/tests/io-client.test.js b/packages/@jsonql/socketio/tests/io-client.test.js new file mode 100644 index 00000000..ad51651b --- /dev/null +++ b/packages/@jsonql/socketio/tests/io-client.test.js @@ -0,0 +1,76 @@ +// basic io client test without auth + +const test = require('ava') + +const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') +const wsClient = require('../main') +const serverSetup = require('./fixtures/server-setup') + +const { join } = require('path') +const fsx = require('fs-extra') + +const publicContract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'public-contract.json')) +const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'contract.json')) + +const debug = require('debug')('jsonql-ws-client:test:io') + +const port = 8004; + +test.before(async t => { + + const { app } = await serverSetup({ + contract, + serverType: JS_WS_SOCKET_IO_NAME + }) + + t.context.server = app.listen(port) + + t.context.client = await wsClient({ + hostname: `http://localhost:${port}`, + serverType: JS_WS_SOCKET_IO_NAME, + contract: publicContract + }) +}) + +test.after(async t => { + t.context.server.close(); +}); + +test.cb('It should able to connect to the socket.io server', t => { + + t.plan(2) + let client = t.context.client + + t.truthy(wsClient.CLIENT_TYPE_INFO) + + client.simple(100) + + client.simple.onResult = (result) => { + t.is(101, result) + t.end() + } +}) + +test.cb('It should able to send message back while its talking to the server', t => { + t.plan(1) + let c = 0; + let client = t.context.client; + client.continuous('Jumping') + client.continuous.onResult = (msg) => { + ++c; + debug(c) + debug('onResult', c , msg) + } + // add a event handler + client.continuous.onMessage = function(msg) { + ++c; + debug(c) + if (c === 3) { + debug(c) + client.continuous.send = 'terminate' + t.pass() + t.end() + } + debug('onMessage', c , msg) + } +}) diff --git a/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js new file mode 100644 index 00000000..94dbce6b --- /dev/null +++ b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-hs.test.js @@ -0,0 +1,86 @@ +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +const { join } = require('path') +const fsx = require('fs-extra') +const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') +// import server +const { + jwtRsaToken, + socketIoGetUserdata, + socketIoChainHSConnect, + socketIoHandshakeAuth +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') +const baseDir = join(__dirname, 'fixtures', 'keys') +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const namespaces = [namespace1, namespace2] +const port = 3003; +const payload = {name: 'Joel'}; +const url = `http://localhost:${port}`; + +test.before( t => { + t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) + t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) + + t.context.token = jwtRsaToken(payload, t.context.privateKey); + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }); + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) // private + const nsp2 = io.of(namespace2) // public + t.context.nsp1 = socketIoHandshakeAuth(nsp1, { + secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), + algorithms: RSA_ALGO + }) + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + +test.cb.skip('It should able to connect to nsp during handshake with the chain connect method', t => { + t.plan(5) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + + nsp1.on('connection', sock => { + let userdata = socketIoGetUserdata(sock) + debug('nsp2 connection established', userdata) + t.is(userdata.name, payload.name) + sock.on('hello1', m => { + t.is(m, 'world1') + }) + }) + // public + nsp2.on('connection', (sock) => { + sock.on('hello2', m => { + // debug('hello1', m); + t.is(m, 'world2') + t.end() + }) + }) + + socketIoChainHSConnect(url, namespaces, token) + .then(nsps => { + t.is(nsps.length, 2) + nsps[0].emit('hello1', 'world1') + setTimeout(() => { + nsps[1].emit('hello2', 'world2') + }, 300) + }) + +}) diff --git a/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js new file mode 100644 index 00000000..7fad0129 --- /dev/null +++ b/packages/@jsonql/socketio/tests/jwt/socketio-chain-connect-rt.test.js @@ -0,0 +1,51 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { + socketIoJwtAuth, + socketIoNodeLogin, + socketIoNodeClientAsync +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3004; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) + // doesn't require login + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + + +test.cb.skip('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { + t.plan(1) + t.pass() + t.end() +}) diff --git a/packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js new file mode 100644 index 00000000..2b0be302 --- /dev/null +++ b/packages/@jsonql/socketio/tests/jwt/socketio-handshake.test.js @@ -0,0 +1,133 @@ +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +const { join } = require('path') +const fsx = require('fs-extra') +const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') +// import server +const { + socketIoHandshakeAuth, + jwtRsaToken, + socketIoGetUserdata, + socketIoNodeClientAsync, + socketIoNodeHandshakeLogin, + chainPromises + +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') +const baseDir = join(__dirname, 'fixtures', 'keys') +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3005; +const payload = {name: 'Joel'}; +const url = `http://localhost:${port}`; + +test.before( t => { + t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) + t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) + + t.context.token = jwtRsaToken(payload, t.context.privateKey); + + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + + t.context.server = server; + // setup socket.io + const io = socketIo(server) + + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoHandshakeAuth(nsp1, { + secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), + algorithms: RSA_ALGO + }) + + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}); + +test.after( t => { + t.context.server.close() +}); + +test.serial.cb('It should able to connect to nsp during handshake', t => { + t.plan(4) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + nsp1.on('connection', (sock) => { + let userdata = socketIoGetUserdata(sock) + debug('nsp1 connection established', userdata) + setTimeout(() => { + sock.emit('hello2', msg) + }, 500) + sock.on('hello1', m => { + // debug('hello1', m); + t.truthy(m) // 1 + }) + }) + nsp2.on('connection', sock2 => { + sock2.on('hello', m => { + debug('hello', m) + t.is(m, 'world') // 2 + }) + }) + socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) + .then(client1 => { + client1.emit('hello1', 'WTF?') + debug('connect to nsp1 established') + client1.on('hello2', message => { + t.is(message, msg) // 3 + client1.disconnect() + t.end() + }) + // try to connect to the public nsp here + socketIoNodeClientAsync(`${url}${namespace2}`) + .then(client2 => { + debug('connect to nsp2 established') + t.truthy(client2) // 4 + client2.emit('hello', 'world') + setTimeout(() => { + client2.disconnect() + }, 500) + }) + + }) + .catch(() => { + debug('login failed!') + }) +}) + +test.serial.cb('Try to use the chain promise method with manually insert connector', t => { + t.plan(3) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + nsp1.on('connection', sock1 => { + let userdata = socketIoGetUserdata(sock1) + t.is(userdata.name, payload.name) + }) + + nsp2.on('connection', sock2 => { + sock2.on('hello', msg => { + t.is(msg, 'world') + t.end() + }) + }) + + let p1 = () => socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) + let p2 = () => socketIoNodeClientAsync(`${url}${namespace2}`) + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length,2) + nsps[1].emit('hello', 'world') + }) +}) diff --git a/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js new file mode 100644 index 00000000..edbd6f13 --- /dev/null +++ b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip-fail.test.js @@ -0,0 +1,60 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { socketIoJwtAuth, socketIoHandshakeAuth, socketIoNodeRoundtripLogin } = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3002; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }); + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret: 'wrong-secret' }) + + t.context.server.listen(port) +}); + +test.after( t => { + t.context.server.close() +}); + +test.cb('It should failed when we pass a wrong secret', t => { + t.plan(1) + t.context.nsp1.then( socket => { + setTimeout(() => { + socket.emit('hello', msg) + }, 500) + }) + + socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + .then(client => { + client.on('hello', message => { + t.is(message, msg) + t.end() + }) + }) + .catch(err => { + debug('did get the catch error!', err) + t.pass() + t.end() + }) + +}) diff --git a/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js new file mode 100644 index 00000000..6a9c498e --- /dev/null +++ b/packages/@jsonql/socketio/tests/jwt/socketio-roundtrip.test.js @@ -0,0 +1,119 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { + socketIoJwtAuth, + socketIoNodeRoundtripLogin, + socketIoNodeClientAsync, + socketIoGetUserdata, + chainPromises +} = require('../main') + +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3001; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) + // doesn't require login + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + +test.serial.cb('It should able to connect using the token', t => { + t.plan(1) + t.context.nsp1.then( socket => { + setTimeout(() => { + socket.emit('hello', msg) + }, 500) + }) + + socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + .then(client => { + client.on('hello', message => { + t.is(message, msg) + client.disconnect() + t.end() + }) + }) + .catch(err => { + debug('error?', err) + }) +}) + +test.serial.cb('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { + t.plan(2) + t.context.nsp2.on('connection', socket => { + debug('connection established') + socket.on('hello', function(msg) { + t.is(msg, 'world') + socket.disconnect() + t.end() + }) + }) + socketIoNodeClientAsync([url, namespace2].join('')).then(nsp => { + t.truthy(nsp) + nsp.emit('hello', 'world') + }) +}) + +test.serial.cb('It should able to round trip connect in sequence using the chain promises', t => { + t.plan(3) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + let p1 = () => socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + let p2 = () => socketIoNodeClientAsync([url, namespace2].join('')) + + // the jwtAuth is a promise interface + + nsp1.then(sock1 => { + let userdata = socketIoGetUserdata(sock1) + t.is(userdata.name, 'Joel', 'should able to decode the token to userdata') + //t.end() + }) + + nsp2.on('connection', sock2 => { + sock2.on('hello', msg => { + t.is(msg, 'world', 'should get the message hello world') + t.end() + }) + }) + + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length, 2, 'should return two nsps') + // send something to the public + setTimeout(() => { + nsps[1].emit('hello', 'world') + }, 500) + + }) + +}) diff --git a/packages/@jsonql/socketio/tests/jwt/ws-handshake.test.js b/packages/@jsonql/socketio/tests/jwt/ws-handshake.test.js new file mode 100644 index 00000000..9829abfd --- /dev/null +++ b/packages/@jsonql/socketio/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/socketio/tests/test-node.test.js b/packages/@jsonql/socketio/tests/test-node.test.js new file mode 100644 index 00000000..af83dde7 --- /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/tests/browser/files/simple-test.js b/packages/@jsonql/ws/tests/browser/files/simple-test.js new file mode 100644 index 00000000..24f733c3 --- /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 00000000..5fe81471 --- /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 00000000..4f4f45ec --- /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 00000000..9af483ab --- /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 00000000..25fd9e0d --- /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 00000000..2187de94 --- /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 00000000..72510498 --- /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 00000000..62d35ef6 --- /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 00000000..3728746d --- /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 00000000..43cfd2b3 --- /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 00000000..65f37ec3 --- /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 00000000..52ceae92 --- /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 00000000..7bd2532a --- /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 00000000..3d6f0446 --- /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 00000000..0a8cb3e8 --- /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 00000000..d2387616 --- /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 00000000..3d468bb9 --- /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 00000000..2cf07351 --- /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 00000000..9144b99a --- /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 00000000..61810eae --- /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 00000000..a7fcd6f4 --- /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 00000000..1bb5ef2b --- /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 00000000..b1d44443 --- /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/socketio-chain-connect-hs.test.js b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js new file mode 100644 index 00000000..94dbce6b --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js @@ -0,0 +1,86 @@ +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +const { join } = require('path') +const fsx = require('fs-extra') +const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') +// import server +const { + jwtRsaToken, + socketIoGetUserdata, + socketIoChainHSConnect, + socketIoHandshakeAuth +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') +const baseDir = join(__dirname, 'fixtures', 'keys') +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const namespaces = [namespace1, namespace2] +const port = 3003; +const payload = {name: 'Joel'}; +const url = `http://localhost:${port}`; + +test.before( t => { + t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) + t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) + + t.context.token = jwtRsaToken(payload, t.context.privateKey); + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }); + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) // private + const nsp2 = io.of(namespace2) // public + t.context.nsp1 = socketIoHandshakeAuth(nsp1, { + secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), + algorithms: RSA_ALGO + }) + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + +test.cb.skip('It should able to connect to nsp during handshake with the chain connect method', t => { + t.plan(5) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + + nsp1.on('connection', sock => { + let userdata = socketIoGetUserdata(sock) + debug('nsp2 connection established', userdata) + t.is(userdata.name, payload.name) + sock.on('hello1', m => { + t.is(m, 'world1') + }) + }) + // public + nsp2.on('connection', (sock) => { + sock.on('hello2', m => { + // debug('hello1', m); + t.is(m, 'world2') + t.end() + }) + }) + + socketIoChainHSConnect(url, namespaces, token) + .then(nsps => { + t.is(nsps.length, 2) + nsps[0].emit('hello1', 'world1') + setTimeout(() => { + nsps[1].emit('hello2', 'world2') + }, 300) + }) + +}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js new file mode 100644 index 00000000..7fad0129 --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js @@ -0,0 +1,51 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { + socketIoJwtAuth, + socketIoNodeLogin, + socketIoNodeClientAsync +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3004; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) + // doesn't require login + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + + +test.cb.skip('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { + t.plan(1) + t.pass() + t.end() +}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js b/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js new file mode 100644 index 00000000..2b0be302 --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js @@ -0,0 +1,133 @@ +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +const { join } = require('path') +const fsx = require('fs-extra') +const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') +// import server +const { + socketIoHandshakeAuth, + jwtRsaToken, + socketIoGetUserdata, + socketIoNodeClientAsync, + socketIoNodeHandshakeLogin, + chainPromises + +} = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') +const baseDir = join(__dirname, 'fixtures', 'keys') +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3005; +const payload = {name: 'Joel'}; +const url = `http://localhost:${port}`; + +test.before( t => { + t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) + t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) + + t.context.token = jwtRsaToken(payload, t.context.privateKey); + + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + + t.context.server = server; + // setup socket.io + const io = socketIo(server) + + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoHandshakeAuth(nsp1, { + secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), + algorithms: RSA_ALGO + }) + + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}); + +test.after( t => { + t.context.server.close() +}); + +test.serial.cb('It should able to connect to nsp during handshake', t => { + t.plan(4) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + nsp1.on('connection', (sock) => { + let userdata = socketIoGetUserdata(sock) + debug('nsp1 connection established', userdata) + setTimeout(() => { + sock.emit('hello2', msg) + }, 500) + sock.on('hello1', m => { + // debug('hello1', m); + t.truthy(m) // 1 + }) + }) + nsp2.on('connection', sock2 => { + sock2.on('hello', m => { + debug('hello', m) + t.is(m, 'world') // 2 + }) + }) + socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) + .then(client1 => { + client1.emit('hello1', 'WTF?') + debug('connect to nsp1 established') + client1.on('hello2', message => { + t.is(message, msg) // 3 + client1.disconnect() + t.end() + }) + // try to connect to the public nsp here + socketIoNodeClientAsync(`${url}${namespace2}`) + .then(client2 => { + debug('connect to nsp2 established') + t.truthy(client2) // 4 + client2.emit('hello', 'world') + setTimeout(() => { + client2.disconnect() + }, 500) + }) + + }) + .catch(() => { + debug('login failed!') + }) +}) + +test.serial.cb('Try to use the chain promise method with manually insert connector', t => { + t.plan(3) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + nsp1.on('connection', sock1 => { + let userdata = socketIoGetUserdata(sock1) + t.is(userdata.name, payload.name) + }) + + nsp2.on('connection', sock2 => { + sock2.on('hello', msg => { + t.is(msg, 'world') + t.end() + }) + }) + + let p1 = () => socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) + let p2 = () => socketIoNodeClientAsync(`${url}${namespace2}`) + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length,2) + nsps[1].emit('hello', 'world') + }) +}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js new file mode 100644 index 00000000..edbd6f13 --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js @@ -0,0 +1,60 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { socketIoJwtAuth, socketIoHandshakeAuth, socketIoNodeRoundtripLogin } = require('../main') +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3002; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }); + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret: 'wrong-secret' }) + + t.context.server.listen(port) +}); + +test.after( t => { + t.context.server.close() +}); + +test.cb('It should failed when we pass a wrong secret', t => { + t.plan(1) + t.context.nsp1.then( socket => { + setTimeout(() => { + socket.emit('hello', msg) + }, 500) + }) + + socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + .then(client => { + client.on('hello', message => { + t.is(message, msg) + t.end() + }) + }) + .catch(err => { + debug('did get the catch error!', err) + t.pass() + t.end() + }) + +}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js new file mode 100644 index 00000000..6a9c498e --- /dev/null +++ b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js @@ -0,0 +1,119 @@ +// testing the socket.io auth with client and server +const test = require('ava') +const http = require('http') +const socketIo = require('socket.io') +// const socketIoClient = require('socket.io-client') +const debug = require('debug')('jsonql-jwt:test:socketio-auth') +// import server +const { + socketIoJwtAuth, + socketIoNodeRoundtripLogin, + socketIoNodeClientAsync, + socketIoGetUserdata, + chainPromises +} = require('../main') + +// import data +const { secret, token, namespace, msg } = require('./fixtures/options') + +const namespace1 = '/' + namespace + '/a'; +const namespace2 = '/' + namespace + '/b'; +const port = 3001; + +const url = `http://localhost:${port}`; + +test.before( t => { + // setup server + const server = http.createServer((req, res) => { + res.writeHead(200, {'Content-Type': 'text/plain'}) + res.write('Hello world!') + res.end() + }) + t.context.server = server; + // setup socket.io + const io = socketIo(server) + const nsp1 = io.of(namespace1) + const nsp2 = io.of(namespace2) + + t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) + // doesn't require login + t.context.nsp2 = nsp2; + + t.context.server.listen(port) +}) + +test.after( t => { + t.context.server.close() +}) + +test.serial.cb('It should able to connect using the token', t => { + t.plan(1) + t.context.nsp1.then( socket => { + setTimeout(() => { + socket.emit('hello', msg) + }, 500) + }) + + socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + .then(client => { + client.on('hello', message => { + t.is(message, msg) + client.disconnect() + t.end() + }) + }) + .catch(err => { + debug('error?', err) + }) +}) + +test.serial.cb('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { + t.plan(2) + t.context.nsp2.on('connection', socket => { + debug('connection established') + socket.on('hello', function(msg) { + t.is(msg, 'world') + socket.disconnect() + t.end() + }) + }) + socketIoNodeClientAsync([url, namespace2].join('')).then(nsp => { + t.truthy(nsp) + nsp.emit('hello', 'world') + }) +}) + +test.serial.cb('It should able to round trip connect in sequence using the chain promises', t => { + t.plan(3) + let nsp1 = t.context.nsp1; + let nsp2 = t.context.nsp2; + let p1 = () => socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) + let p2 = () => socketIoNodeClientAsync([url, namespace2].join('')) + + // the jwtAuth is a promise interface + + nsp1.then(sock1 => { + let userdata = socketIoGetUserdata(sock1) + t.is(userdata.name, 'Joel', 'should able to decode the token to userdata') + //t.end() + }) + + nsp2.on('connection', sock2 => { + sock2.on('hello', msg => { + t.is(msg, 'world', 'should get the message hello world') + t.end() + }) + }) + + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length, 2, 'should return two nsps') + // send something to the public + setTimeout(() => { + nsps[1].emit('hello', 'world') + }, 500) + + }) + +}) 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 00000000..9829abfd --- /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 00000000..af83dde7 --- /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/@jsonql/ws/tests/ws-client-auth-login.test.js b/packages/@jsonql/ws/tests/ws-client-auth-login.test.js new file mode 100644 index 00000000..833dfc4d --- /dev/null +++ b/packages/@jsonql/ws/tests/ws-client-auth-login.test.js @@ -0,0 +1,103 @@ +// standard ws client test without auth +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') + +const wsClient = require('../main') +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 } = require('jsonql-constants') +const payload = {name: 'Joel'}; + +const debug = require('debug')('jsonql-ws-client:test:ws-auth-login') + +const port = 8003; + +test.before(async t => { + + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + serverType: 'ws', + enableAuth: true, + keysDir: join(__dirname, 'fixtures', 'keys') + }) + t.context.server = app.listen(port) + // without the token + t.context.client = await wsClient({ + serverType: 'ws', + hostname: `ws://localhost:${port}`, + contract: publicContract, + enableAuth: true, + useJwt: true + }) + +}) + +test.after(t => { + t.context.server.close() +}) +// access the public namespace + +// @BUG the login is not quite 100% yet, but we need to test this more +// in the browser, the problem is this is bi-directional and +// when we add a client to connect to the server, it could create some +// strange effects. We might have to issue an LOGOUT before we attempt to +// LOGIN to clear out all the existing connections + +test.serial.cb('It should able to connect to the ws server public namespace', t => { + let ctn = 0; + t.plan(2) + let client = t.context.client; + client.pinging('Hello') + + client.pinging.onResult= (res) => { + debug('res', res) + t.is(res, 'connection established') + client.pinging.send = 'ping'; + } + // the send is happen after the result return on the server side + client.pinging.onMessage = function(msg) { + if (msg==='pong') { + client.pinging.send = 'pong'; + } else { + client.pinging.send = 'giving up'; + debug('TEST SHOULD HALT HERE') + t.pass() + t.end() + } + } +}) + +test.serial.cb('It should trigger the login call here', t => { + t.plan(2) + let client = t.context.client; + let ctn = 0; + // add onReady and wait for the login to happen + client.onReady = function(namespace) { + debug('onReady -->', namespace, client.simple.myNamespace) + if (namespace === client.simple.myNamespace) { + client.simple(200) + client.simple.onResult = (result) => { + debug('simple onResult pass (3)', result) + t.pass() + t.end() + } + } + } + + client.simple(100) + client.simple.onError = (error) => { + if (!ctn) { + t.is(NOT_LOGIN_ERR_MSG, error.message, 'pass (2)') + const token = genToken(payload) + client.login(token) + ++ctn; + } + } +}) diff --git a/packages/@jsonql/ws/tests/ws-client-auth.test.js b/packages/@jsonql/ws/tests/ws-client-auth.test.js new file mode 100644 index 00000000..f7961b25 --- /dev/null +++ b/packages/@jsonql/ws/tests/ws-client-auth.test.js @@ -0,0 +1,94 @@ +// standard ws client test without auth +const test = require('ava') + +const wsClient = require('../main') +const serverSetup = require('./fixtures/server-setup') + +const { join } = require('path') +const fsx = require('fs-extra') + +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 debug = require('debug')('jsonql-ws-client:test:ws-auth') + +const payload = {name: 'Joel'}; +const token = genToken(payload) +const port = 8002; + +test.before(async t => { + + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + serverType: 'ws', + enableAuth: true, + // useJwt: true, + keysDir: join(__dirname, 'fixtures', 'keys') + }) + t.context.server = app.listen(port) + + t.context.client = await wsClient({ + token, + serverType: 'ws', + hostname: `ws://localhost:${port}`, + contract: publicContract, + enableAuth: true, + useJwt: true + }) +}) + +test.after(t => { + t.context.server.close() +}) + +test.serial.cb('It should able to connect to the WebSocket public namespace', t => { + t.plan(2) + let client = t.context.client; + client.pinging('Hello') + + client.pinging.onResult = res => { + debug('res', res) + t.is(res, 'connection established') + client.pinging.send = 'ping'; + } + // start the ping pong game + client.pinging.onMessage = function(msg) { + if (msg==='pong') { + client.pinging.send = 'pong'; + } else { + client.pinging.send = 'giving up'; + t.is(msg, 'ping') + t.end() + } + } +}) + +test.serial.cb('It should able to connect to a WebSocket private namespace', t => { + t.plan(2) + let client = t.context.client; + client.onReady = (w) => { + debug('onReady again', w) + } + + client.sendExtraMsg(100) + + client.sendExtraMsg.onResult = (result) => { + t.is(101, result) + t.end() + } + + client.sendExtraMsg.onMessage = function(num) { + t.is(102, num) + } + + client.onReady = (w) => { + debug('onReady -->', w) + return w; + } + +}) diff --git a/packages/@jsonql/ws/tests/ws-client-chain.test.js b/packages/@jsonql/ws/tests/ws-client-chain.test.js new file mode 100644 index 00000000..612acecc --- /dev/null +++ b/packages/@jsonql/ws/tests/ws-client-chain.test.js @@ -0,0 +1,99 @@ +// testing the chain methods +const test = require('ava') +const { join } = require('path') +const fsx = require('fs-extra') + +const { + chainPromises, + wsNodeClient, + wsNodeAuthClient +} = require('jsonql-jwt') + + +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 } = require('jsonql-constants') + +const payload = {name: 'Joel'}; +const token = genToken(payload) + +const debug = require('debug')('jsonql-ws-client:test:ws-client-chain') + +const port = 8009; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract, + contractDir, + resolverDir: join(__dirname, 'fixtures', 'resolvers'), + serverType: 'ws', + enableAuth: true, + keysDir: join(__dirname, 'fixtures', 'keys') + }) + t.context.server = app.listen(port) + + let baseUrl = `ws://localhost:${port}`; + t.context.nsp1url = [baseUrl, 'jsonql/private'].join('/') + t.context.nsp2url = [baseUrl, 'jsonql/public'].join('/') +}) + +test.serial.cb('First test the connection individually', t => { + t.plan(2) + let ws1 = wsNodeAuthClient(t.context.nsp1url, token) + let ws2 = wsNodeClient(t.context.nsp2url) + + ws1.onopen = function() { + t.pass() + ws1.terminate() + } + + ws2.onopen = function() { + t.pass() + ws2.terminate() + t.end() + } + +}) +// @BUG whenever I wrap this code in the promise the ws just hang up +test.serial.cb.skip('Try to create a promise based ws client and using the chainPromises method to login', t => { + t.plan(1) + + let p1 = () => ( + new Promise((resolver, rejecter) => { + let ws1 = wsNodeAuthClient(nsp1url, token) + let timer; + setTimeout(() => { + rejecter() + }, 5000) + ws1.onopen = () => { + clearTimeout(timer) + resolver(ws1) + } + }) + ) + let p2 = () => ( + new Promise((resolver, rejecter) => { + let ws2 = wsNodeClient(nsp2url) + let timer; + setTimeout(() => { + rejecter() + }, 5000) + ws2.onopen = () => { + clearTimeout(timer) + resolver(ws2) + } + }) + ) + + chainPromises([p1(), p2()]) + .then(nsps => { + t.is(nsps.length, 2) + t.end() + }) + +}) diff --git a/packages/@jsonql/ws/tests/ws-client.test.js b/packages/@jsonql/ws/tests/ws-client.test.js new file mode 100644 index 00000000..9edcd56c --- /dev/null +++ b/packages/@jsonql/ws/tests/ws-client.test.js @@ -0,0 +1,83 @@ +// standard ws client test without auth +const test = require('ava') +const { JS_WS_NAME } = require('jsonql-constants') +const wsClient = require('../main') +const serverSetup = require('./fixtures/server-setup') + +const { join } = require('path') +const fsx = require('fs-extra') + +const publicContract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'public-contract.json')) +const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'contract.json')) + +const debug = require('debug')('jsonql-ws-client:test:ws') + +const port = 8001; + +test.before(async t => { + const { io, app } = await serverSetup({ + contract + }) + t.context.server = app.listen(port) + + t.context.client = await wsClient({ + hostname: `ws://localhost:${port}`, + serverType: JS_WS_NAME, + contract: publicContract + }) + +}) + +test.after(t => { + t.context.server.close() +}) + +test.cb('It should able to connect to the ws server', t => { + t.plan(2) + let client = t.context.client + + t.truthy(wsClient.CLIENT_TYPE_INFO) + + client.simple(100) + client.simple.onResult = (result) => { + t.is(101, result) + t.end() + } +}) + +test.cb('It should able to handle error', t => { + t.plan(1) + let client = t.context.client; + + client.throwError() + + client.throwError.onError = (error) => { + debug(error) + t.truthy(error) + t.end() + } +}) + +test.cb('It should able to send message back while its talking to the server', t => { + t.plan(1) + let c = 0; + let client = t.context.client; + client.continuous('Jumping') + client.continuous.onResult = (msg) => { + ++c; + debug(c) + debug('onResult', c , msg) + } + // add a event handler + client.continuous.onMessage = function(msg) { + ++c; + debug(c) + if (c === 3) { + debug(c) + client.continuous.send = 'terminate' + t.pass() + t.end() + } + debug('onMessage', c , msg) + } +}) -- Gitee From 2cbcb5ba65b546738a0a4a5dd35a0e06dee7241b Mon Sep 17 00:00:00 2001 From: joelchu Date: Thu, 5 Sep 2019 10:04:23 +0100 Subject: [PATCH 58/59] move build script and clean up the old repo --- .../socketio}/rollup.config.js | 0 .../socketio}/rollup.config.node.js | 0 packages/@jsonql/ws/rollup.config.js | 78 ++++++++++ packages/@jsonql/ws/rollup.config.node.js | 85 +++++++++++ .../jwt/socketio-chain-connect-hs.test.js | 86 ----------- .../jwt/socketio-chain-connect-rt.test.js | 51 ------- .../ws/tests/jwt/socketio-handshake.test.js | 133 ------------------ .../tests/jwt/socketio-roundtrip-fail.test.js | 60 -------- .../ws/tests/jwt/socketio-roundtrip.test.js | 119 ---------------- packages/ws-client/package.json | 24 ---- .../tests/browser/files/simple-test.js | 25 ---- packages/ws-client/tests/browser/run-qunit.js | 98 ------------- .../tests/browser/webroot/index.html | 107 -------------- .../tests/browser/webroot/qunit-log.js | 29 ---- .../tests/io-chain-connection.test.js | 49 ------- .../tests/io-client-hs-auth-login.test.js | 81 ----------- .../ws-client/tests/io-client-hs-auth.test.js | 70 --------- .../tests/io-client-rt-auth-login.test.js | 95 ------------- .../ws-client/tests/io-client-rt-auth.test.js | 61 -------- packages/ws-client/tests/io-client.test.js | 76 ---------- .../jwt/socketio-chain-connect-hs.test.js | 86 ----------- .../jwt/socketio-chain-connect-rt.test.js | 51 ------- .../tests/jwt/socketio-handshake.test.js | 133 ------------------ .../tests/jwt/socketio-roundtrip-fail.test.js | 60 -------- .../tests/jwt/socketio-roundtrip.test.js | 119 ---------------- .../ws-client/tests/jwt/ws-handshake.test.js | 104 -------------- .../tests/ws-client-auth-login.test.js | 103 -------------- .../ws-client/tests/ws-client-auth.test.js | 94 ------------- .../ws-client/tests/ws-client-chain.test.js | 99 ------------- packages/ws-client/tests/ws-client.test.js | 83 ----------- 30 files changed, 163 insertions(+), 2096 deletions(-) rename packages/{ws-client => @jsonql/socketio}/rollup.config.js (100%) rename packages/{ws-client => @jsonql/socketio}/rollup.config.node.js (100%) create mode 100644 packages/@jsonql/ws/rollup.config.js create mode 100644 packages/@jsonql/ws/rollup.config.node.js delete mode 100644 packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js delete mode 100644 packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js delete mode 100644 packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js delete mode 100644 packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js delete mode 100644 packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js delete mode 100644 packages/ws-client/tests/browser/files/simple-test.js delete mode 100644 packages/ws-client/tests/browser/run-qunit.js delete mode 100644 packages/ws-client/tests/browser/webroot/index.html delete mode 100644 packages/ws-client/tests/browser/webroot/qunit-log.js delete mode 100644 packages/ws-client/tests/io-chain-connection.test.js delete mode 100644 packages/ws-client/tests/io-client-hs-auth-login.test.js delete mode 100644 packages/ws-client/tests/io-client-hs-auth.test.js delete mode 100644 packages/ws-client/tests/io-client-rt-auth-login.test.js delete mode 100644 packages/ws-client/tests/io-client-rt-auth.test.js delete mode 100644 packages/ws-client/tests/io-client.test.js delete mode 100644 packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js delete mode 100644 packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js delete mode 100644 packages/ws-client/tests/jwt/socketio-handshake.test.js delete mode 100644 packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js delete mode 100644 packages/ws-client/tests/jwt/socketio-roundtrip.test.js delete mode 100644 packages/ws-client/tests/jwt/ws-handshake.test.js delete mode 100644 packages/ws-client/tests/ws-client-auth-login.test.js delete mode 100644 packages/ws-client/tests/ws-client-auth.test.js delete mode 100644 packages/ws-client/tests/ws-client-chain.test.js delete mode 100644 packages/ws-client/tests/ws-client.test.js 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/@jsonql/ws/rollup.config.js b/packages/@jsonql/ws/rollup.config.js new file mode 100644 index 00000000..e6d3778e --- /dev/null +++ b/packages/@jsonql/ws/rollup.config.js @@ -0,0 +1,78 @@ +/** + * Rollup config for browser version of the + */ +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: umd` + }) +] + +if (process.env.NODE_ENV === 'production') { + plugins.push( terser() ) +} +plugins.push( size() ) + +let config = { + input: join(__dirname, 'index.js'), + output: { + name: 'jsonqlWsClient', + file: join(__dirname, 'dist', 'jsonql-ws-client.js'), + format: 'umd', + sourcemap: true, + 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/@jsonql/ws/rollup.config.node.js b/packages/@jsonql/ws/rollup.config.node.js new file mode 100644 index 00000000..d6c593b7 --- /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/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js deleted file mode 100644 index 94dbce6b..00000000 --- a/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-hs.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -const { join } = require('path') -const fsx = require('fs-extra') -const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') -// import server -const { - jwtRsaToken, - socketIoGetUserdata, - socketIoChainHSConnect, - socketIoHandshakeAuth -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') -const baseDir = join(__dirname, 'fixtures', 'keys') -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const namespaces = [namespace1, namespace2] -const port = 3003; -const payload = {name: 'Joel'}; -const url = `http://localhost:${port}`; - -test.before( t => { - t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) - t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) - - t.context.token = jwtRsaToken(payload, t.context.privateKey); - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }); - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) // private - const nsp2 = io.of(namespace2) // public - t.context.nsp1 = socketIoHandshakeAuth(nsp1, { - secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), - algorithms: RSA_ALGO - }) - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - -test.cb.skip('It should able to connect to nsp during handshake with the chain connect method', t => { - t.plan(5) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - - nsp1.on('connection', sock => { - let userdata = socketIoGetUserdata(sock) - debug('nsp2 connection established', userdata) - t.is(userdata.name, payload.name) - sock.on('hello1', m => { - t.is(m, 'world1') - }) - }) - // public - nsp2.on('connection', (sock) => { - sock.on('hello2', m => { - // debug('hello1', m); - t.is(m, 'world2') - t.end() - }) - }) - - socketIoChainHSConnect(url, namespaces, token) - .then(nsps => { - t.is(nsps.length, 2) - nsps[0].emit('hello1', 'world1') - setTimeout(() => { - nsps[1].emit('hello2', 'world2') - }, 300) - }) - -}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js b/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js deleted file mode 100644 index 7fad0129..00000000 --- a/packages/@jsonql/ws/tests/jwt/socketio-chain-connect-rt.test.js +++ /dev/null @@ -1,51 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { - socketIoJwtAuth, - socketIoNodeLogin, - socketIoNodeClientAsync -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3004; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) - // doesn't require login - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - - -test.cb.skip('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { - t.plan(1) - t.pass() - t.end() -}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js b/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js deleted file mode 100644 index 2b0be302..00000000 --- a/packages/@jsonql/ws/tests/jwt/socketio-handshake.test.js +++ /dev/null @@ -1,133 +0,0 @@ -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -const { join } = require('path') -const fsx = require('fs-extra') -const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') -// import server -const { - socketIoHandshakeAuth, - jwtRsaToken, - socketIoGetUserdata, - socketIoNodeClientAsync, - socketIoNodeHandshakeLogin, - chainPromises - -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') -const baseDir = join(__dirname, 'fixtures', 'keys') -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3005; -const payload = {name: 'Joel'}; -const url = `http://localhost:${port}`; - -test.before( t => { - t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) - t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) - - t.context.token = jwtRsaToken(payload, t.context.privateKey); - - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - - t.context.server = server; - // setup socket.io - const io = socketIo(server) - - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoHandshakeAuth(nsp1, { - secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), - algorithms: RSA_ALGO - }) - - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}); - -test.after( t => { - t.context.server.close() -}); - -test.serial.cb('It should able to connect to nsp during handshake', t => { - t.plan(4) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - nsp1.on('connection', (sock) => { - let userdata = socketIoGetUserdata(sock) - debug('nsp1 connection established', userdata) - setTimeout(() => { - sock.emit('hello2', msg) - }, 500) - sock.on('hello1', m => { - // debug('hello1', m); - t.truthy(m) // 1 - }) - }) - nsp2.on('connection', sock2 => { - sock2.on('hello', m => { - debug('hello', m) - t.is(m, 'world') // 2 - }) - }) - socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) - .then(client1 => { - client1.emit('hello1', 'WTF?') - debug('connect to nsp1 established') - client1.on('hello2', message => { - t.is(message, msg) // 3 - client1.disconnect() - t.end() - }) - // try to connect to the public nsp here - socketIoNodeClientAsync(`${url}${namespace2}`) - .then(client2 => { - debug('connect to nsp2 established') - t.truthy(client2) // 4 - client2.emit('hello', 'world') - setTimeout(() => { - client2.disconnect() - }, 500) - }) - - }) - .catch(() => { - debug('login failed!') - }) -}) - -test.serial.cb('Try to use the chain promise method with manually insert connector', t => { - t.plan(3) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - nsp1.on('connection', sock1 => { - let userdata = socketIoGetUserdata(sock1) - t.is(userdata.name, payload.name) - }) - - nsp2.on('connection', sock2 => { - sock2.on('hello', msg => { - t.is(msg, 'world') - t.end() - }) - }) - - let p1 = () => socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) - let p2 = () => socketIoNodeClientAsync(`${url}${namespace2}`) - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length,2) - nsps[1].emit('hello', 'world') - }) -}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js deleted file mode 100644 index edbd6f13..00000000 --- a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip-fail.test.js +++ /dev/null @@ -1,60 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { socketIoJwtAuth, socketIoHandshakeAuth, socketIoNodeRoundtripLogin } = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3002; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }); - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret: 'wrong-secret' }) - - t.context.server.listen(port) -}); - -test.after( t => { - t.context.server.close() -}); - -test.cb('It should failed when we pass a wrong secret', t => { - t.plan(1) - t.context.nsp1.then( socket => { - setTimeout(() => { - socket.emit('hello', msg) - }, 500) - }) - - socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - .then(client => { - client.on('hello', message => { - t.is(message, msg) - t.end() - }) - }) - .catch(err => { - debug('did get the catch error!', err) - t.pass() - t.end() - }) - -}) diff --git a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js b/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js deleted file mode 100644 index 6a9c498e..00000000 --- a/packages/@jsonql/ws/tests/jwt/socketio-roundtrip.test.js +++ /dev/null @@ -1,119 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { - socketIoJwtAuth, - socketIoNodeRoundtripLogin, - socketIoNodeClientAsync, - socketIoGetUserdata, - chainPromises -} = require('../main') - -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3001; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) - // doesn't require login - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - -test.serial.cb('It should able to connect using the token', t => { - t.plan(1) - t.context.nsp1.then( socket => { - setTimeout(() => { - socket.emit('hello', msg) - }, 500) - }) - - socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - .then(client => { - client.on('hello', message => { - t.is(message, msg) - client.disconnect() - t.end() - }) - }) - .catch(err => { - debug('error?', err) - }) -}) - -test.serial.cb('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { - t.plan(2) - t.context.nsp2.on('connection', socket => { - debug('connection established') - socket.on('hello', function(msg) { - t.is(msg, 'world') - socket.disconnect() - t.end() - }) - }) - socketIoNodeClientAsync([url, namespace2].join('')).then(nsp => { - t.truthy(nsp) - nsp.emit('hello', 'world') - }) -}) - -test.serial.cb('It should able to round trip connect in sequence using the chain promises', t => { - t.plan(3) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - let p1 = () => socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - let p2 = () => socketIoNodeClientAsync([url, namespace2].join('')) - - // the jwtAuth is a promise interface - - nsp1.then(sock1 => { - let userdata = socketIoGetUserdata(sock1) - t.is(userdata.name, 'Joel', 'should able to decode the token to userdata') - //t.end() - }) - - nsp2.on('connection', sock2 => { - sock2.on('hello', msg => { - t.is(msg, 'world', 'should get the message hello world') - t.end() - }) - }) - - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length, 2, 'should return two nsps') - // send something to the public - setTimeout(() => { - nsps[1].emit('hello', 'world') - }, 500) - - }) - -}) diff --git a/packages/ws-client/package.json b/packages/ws-client/package.json index 001dc41c..69177958 100755 --- a/packages/ws-client/package.json +++ b/packages/ws-client/package.json @@ -34,30 +34,6 @@ "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": { diff --git a/packages/ws-client/tests/browser/files/simple-test.js b/packages/ws-client/tests/browser/files/simple-test.js deleted file mode 100644 index 24f733c3..00000000 --- a/packages/ws-client/tests/browser/files/simple-test.js +++ /dev/null @@ -1,25 +0,0 @@ - -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/ws-client/tests/browser/run-qunit.js b/packages/ws-client/tests/browser/run-qunit.js deleted file mode 100644 index 5fe81471..00000000 --- a/packages/ws-client/tests/browser/run-qunit.js +++ /dev/null @@ -1,98 +0,0 @@ -// 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/ws-client/tests/browser/webroot/index.html b/packages/ws-client/tests/browser/webroot/index.html deleted file mode 100644 index 4f4f45ec..00000000 --- a/packages/ws-client/tests/browser/webroot/index.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - QUnit testing for jsonql-client - - - - -
-
- - - - - - - - - - diff --git a/packages/ws-client/tests/browser/webroot/qunit-log.js b/packages/ws-client/tests/browser/webroot/qunit-log.js deleted file mode 100644 index 9af483ab..00000000 --- a/packages/ws-client/tests/browser/webroot/qunit-log.js +++ /dev/null @@ -1,29 +0,0 @@ -;(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/ws-client/tests/io-chain-connection.test.js b/packages/ws-client/tests/io-chain-connection.test.js deleted file mode 100644 index 59569346..00000000 --- a/packages/ws-client/tests/io-chain-connection.test.js +++ /dev/null @@ -1,49 +0,0 @@ -// We need to make sure the private nsps connected and establish connection -// before we call the next client, otherwise it will break the auth connection -const test = require('ava') -const debug = require('debug')('jsonql-ws-client:test:io-chain-connection') -const { chainPromises } = require('jsonql-jwt') -// const chainCreateNsps = require('../src/io/chain-create-nsps') - -test('just testing the different between concat and push', t => { - let baseArr = [] - - let result = baseArr.push(1,2,3) - - debug(result) - - t.is(3, baseArr.length) - -}) - - -test('Test concat array without concat', t => { - const args = [1,2,3] - const newArgs = [4, ...args] - t.is(4, newArgs.length) - - const anotherNewArr = [5, ...Array(4,3,2,1)] - - debug(newArgs, anotherNewArr) -}) - -test.cb('It should able to run the array of promise one after another', t => { - t.plan(1) - let ps = [] - for (let i = 0; i < 2; ++i) { - ps.push( - new Promise(resolver => { - setTimeout(() => { - resolver(i+1) - }, 500) - }) - ) - } - // this is transform by esm on the fly so we got that annoying default key again - chainPromises(ps) - .then(result => { - debug(result) - t.pass() - t.end() - }) -}) diff --git a/packages/ws-client/tests/io-client-hs-auth-login.test.js b/packages/ws-client/tests/io-client-hs-auth-login.test.js deleted file mode 100644 index 4e2f23bf..00000000 --- a/packages/ws-client/tests/io-client-hs-auth-login.test.js +++ /dev/null @@ -1,81 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') -const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') - -const wsClient = require('../main') -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 keysDir = join(__dirname, 'fixtures', 'keys') - -const debug = require('debug')('jsonql-ws-client:test:io-hs-login') - -const port = 8008; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract, - contractDir, - resolverDir: join(__dirname, 'fixtures', 'resolvers'), - keysDir, - serverType: JS_WS_SOCKET_IO_NAME, - enableAuth: true, - useJwt: true - }) - - t.context.server = app.listen(port) - - t.context.client = await wsClient({ - serverType: JS_WS_SOCKET_IO_NAME, - hostname: `ws://localhost:${port}`, - contract: publicContract, - enableAuth: true, - useJwt: true - }) -}) - -test.after(t => { - t.context.server.close() -}) - -test.serial.cb('It should able to connect to the socket.io server public namespace', t => { - t.plan(1) - let client = t.context.client; - client.pinging('Hello') - client.pinging.onResult = (res) => { - debug('res', res) - t.is(res, 'connection established') - t.end() - } -}) -// this is confirm fucked becasue of the socket.io bug -// https://github.com/auth0-community/socketio-jwt/issues/95 -test.serial.cb('It should able to call the login method and establish socket.io connection using handshake', t => { - t.plan(1) - let client = t.context.client; - const payload = {name: 'Joel'} - const token = genToken(payload) - client.login(token) - // add onReady and wait for the login to happen - client.onReady = function(namespace) { - debug('--> onReady', namespace, client.sendExtraMsg.myNamespace) - if (namespace === client.sendExtraMsg.myNamespace) { - client.sendExtraMsg(200) - client.sendExtraMsg.onResult = (result) => { - debug('login success', result) - t.is(201, result) - t.end() - } - // this should work - // but this will happen before the above Promise.resolve - client.sendExtraMsg.onMessage = function(result) { - debug('onMessge got news', result) - } - } - } -}) diff --git a/packages/ws-client/tests/io-client-hs-auth.test.js b/packages/ws-client/tests/io-client-hs-auth.test.js deleted file mode 100644 index 90f38ca5..00000000 --- a/packages/ws-client/tests/io-client-hs-auth.test.js +++ /dev/null @@ -1,70 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') -const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') -const debug = require('debug')('jsonql-ws-client:test:io-hs') - -const wsClient = require('../main') -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 keysDir = join(__dirname, 'fixtures', 'keys') - -const { - chainPromises, - socketIoNodeHandshakeLogin, - socketIoNodeClientAsync -} = require('jsonql-jwt') - -const payload = {name: 'Joel'} -const token = genToken(payload) -const port = 8007; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract, - contractDir, - keysDir, - serverType: JS_WS_SOCKET_IO_NAME, - enableAuth: true, - useJwt: true - }) - - t.context.server = app.listen(port) - /* - t.context.client = await wsClient({ - token, - serverType: JS_WS_SOCKET_IO_NAME, - hostname: `ws://localhost:${port}`, - contract: publicContract, - enableAuth: true, - useJwt: true - }) - */ - -}) - -test.after(t => { - t.context.server.close() -}) - -test.cb('Just testing the chainPromises method with socket.io round trip login method', t => { - t.plan(1) - - let baseUrl = `ws://localhost:${port}/jsonql` - let nsp1url = [baseUrl, 'private'].join('/') - let nsp2url = [baseUrl, 'public'].join('/') - - let p1 = () => socketIoNodeHandshakeLogin(nsp1url, token) - let p2 = () => socketIoNodeClientAsync(nsp2url) - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length, 2) - t.end() - }) -}) diff --git a/packages/ws-client/tests/io-client-rt-auth-login.test.js b/packages/ws-client/tests/io-client-rt-auth-login.test.js deleted file mode 100644 index e87f56ae..00000000 --- a/packages/ws-client/tests/io-client-rt-auth-login.test.js +++ /dev/null @@ -1,95 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') -const { JS_WS_SOCKET_IO_NAME, IO_ROUNDTRIP_LOGIN } = require('jsonql-constants') -const debug = require('debug')('jsonql-ws-client:test:io-rt-login') - -const wsClient = require('../main') -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 keysDir = join(__dirname, 'fixtures', 'keys') -const secret = '123456789'; -const port = 8006; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract, - contractDir, - keysDir, - serverType: JS_WS_SOCKET_IO_NAME, - enableAuth: true, - useJwt: secret // <-- this is the secret - }) - - t.context.server = app.listen(port) - - t.context.client = await wsClient({ - serverType: JS_WS_SOCKET_IO_NAME, - hostname: `ws://localhost:${port}`, - contract: publicContract, - enableAuth: true, - useJwt: IO_ROUNDTRIP_LOGIN // <-- DON'T PASS THE SERVER SECRET! - }) -}) - -test.after(t => { - t.context.server.close() -}) - - -test.serial.cb('It should able to connect to the socket.io server public namespace', t => { - t.plan(1) - let client = t.context.client; - client.pinging('Hello') - client.pinging.onResult = (res) => { - debug('res', res) - t.is(res, 'connection established') - t.end() - } -}) - -test.serial.cb.skip('It should not able to connect to the socket.io private namespace at this point', t => { - t.plan(1) - let client = t.context.client; - client.sendExtraMsg(100) - // @TODO this one need to take a look at - client.sendExtraMsg.onError = error => { - debug('NOT_LOGIN_ERR_MSG', NOT_LOGIN_ERR_MSG, error.message) - t.is(NOT_LOGIN_ERR_MSG, error.message) - t.end() - } -}) - -test.serial.cb('It should able to call the login method and establish socket.io connection using the round trip method', t => { - t.plan(1) - let client = t.context.client; - const payload = {name: 'Joel'} - const token = genToken(payload, secret) - debug('call login', token) - - client.login(token) - - // add onReady and wait for the login to happen - - client.onReady = function(namespace) { - debug('--> onReady', namespace) - if (namespace === 'jsonql/private') { - client.sendExtraMsg(200) - client.sendExtraMsg.onResult = (result) => { - debug('login success', result) - t.is(201, result) - t.end() - } - // this should work - // but this will happen before the above Promise.resolve - client.sendExtraMsg.onMessage = function(result) { - debug('onMessge got news', result) - } - } - } -}) diff --git a/packages/ws-client/tests/io-client-rt-auth.test.js b/packages/ws-client/tests/io-client-rt-auth.test.js deleted file mode 100644 index 7ceff8fd..00000000 --- a/packages/ws-client/tests/io-client-rt-auth.test.js +++ /dev/null @@ -1,61 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') -const { JS_WS_SOCKET_IO_NAME, IO_ROUNDTRIP_LOGIN } = require('jsonql-constants') -const debug = require('debug')('jsonql-ws-client:test:io-rt') - -const wsClient = require('../main') -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 keysDir = join(__dirname, 'fixtures', 'keys') - -const { - chainPromises, - socketIoNodeRoundtripLogin, - socketIoNodeClientAsync -} = require('jsonql-jwt') - -const secret = '12345678'; -const payload = {name: 'Joel'} -const token = genToken(payload, secret) - -const port = 8005; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract, - contractDir, - keysDir, - serverType: JS_WS_SOCKET_IO_NAME, - enableAuth: true, - useJwt: secret // <-- this is the secret - }) - - t.context.server = app.listen(port) -}) - -test.after(t => { - t.context.server.close() -}) - -test.cb('Just testing the chainPromises method with socket.io round trip login method', t => { - t.plan(1) - - let baseUrl = `ws://localhost:${port}/jsonql` - let nsp1url = [baseUrl, 'private'].join('/') - let nsp2url = [baseUrl, 'public'].join('/') - - let p1 = () => socketIoNodeRoundtripLogin(nsp1url, token) - let p2 = () => socketIoNodeClientAsync(nsp2url) - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length, 2) - t.end() - }) -}) diff --git a/packages/ws-client/tests/io-client.test.js b/packages/ws-client/tests/io-client.test.js deleted file mode 100644 index ad51651b..00000000 --- a/packages/ws-client/tests/io-client.test.js +++ /dev/null @@ -1,76 +0,0 @@ -// basic io client test without auth - -const test = require('ava') - -const { JS_WS_SOCKET_IO_NAME } = require('jsonql-constants') -const wsClient = require('../main') -const serverSetup = require('./fixtures/server-setup') - -const { join } = require('path') -const fsx = require('fs-extra') - -const publicContract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'public-contract.json')) -const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'contract.json')) - -const debug = require('debug')('jsonql-ws-client:test:io') - -const port = 8004; - -test.before(async t => { - - const { app } = await serverSetup({ - contract, - serverType: JS_WS_SOCKET_IO_NAME - }) - - t.context.server = app.listen(port) - - t.context.client = await wsClient({ - hostname: `http://localhost:${port}`, - serverType: JS_WS_SOCKET_IO_NAME, - contract: publicContract - }) -}) - -test.after(async t => { - t.context.server.close(); -}); - -test.cb('It should able to connect to the socket.io server', t => { - - t.plan(2) - let client = t.context.client - - t.truthy(wsClient.CLIENT_TYPE_INFO) - - client.simple(100) - - client.simple.onResult = (result) => { - t.is(101, result) - t.end() - } -}) - -test.cb('It should able to send message back while its talking to the server', t => { - t.plan(1) - let c = 0; - let client = t.context.client; - client.continuous('Jumping') - client.continuous.onResult = (msg) => { - ++c; - debug(c) - debug('onResult', c , msg) - } - // add a event handler - client.continuous.onMessage = function(msg) { - ++c; - debug(c) - if (c === 3) { - debug(c) - client.continuous.send = 'terminate' - t.pass() - t.end() - } - debug('onMessage', c , msg) - } -}) diff --git a/packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js b/packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js deleted file mode 100644 index 94dbce6b..00000000 --- a/packages/ws-client/tests/jwt/socketio-chain-connect-hs.test.js +++ /dev/null @@ -1,86 +0,0 @@ -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -const { join } = require('path') -const fsx = require('fs-extra') -const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') -// import server -const { - jwtRsaToken, - socketIoGetUserdata, - socketIoChainHSConnect, - socketIoHandshakeAuth -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') -const baseDir = join(__dirname, 'fixtures', 'keys') -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const namespaces = [namespace1, namespace2] -const port = 3003; -const payload = {name: 'Joel'}; -const url = `http://localhost:${port}`; - -test.before( t => { - t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) - t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) - - t.context.token = jwtRsaToken(payload, t.context.privateKey); - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }); - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) // private - const nsp2 = io.of(namespace2) // public - t.context.nsp1 = socketIoHandshakeAuth(nsp1, { - secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), - algorithms: RSA_ALGO - }) - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - -test.cb.skip('It should able to connect to nsp during handshake with the chain connect method', t => { - t.plan(5) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - - nsp1.on('connection', sock => { - let userdata = socketIoGetUserdata(sock) - debug('nsp2 connection established', userdata) - t.is(userdata.name, payload.name) - sock.on('hello1', m => { - t.is(m, 'world1') - }) - }) - // public - nsp2.on('connection', (sock) => { - sock.on('hello2', m => { - // debug('hello1', m); - t.is(m, 'world2') - t.end() - }) - }) - - socketIoChainHSConnect(url, namespaces, token) - .then(nsps => { - t.is(nsps.length, 2) - nsps[0].emit('hello1', 'world1') - setTimeout(() => { - nsps[1].emit('hello2', 'world2') - }, 300) - }) - -}) diff --git a/packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js b/packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js deleted file mode 100644 index 7fad0129..00000000 --- a/packages/ws-client/tests/jwt/socketio-chain-connect-rt.test.js +++ /dev/null @@ -1,51 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { - socketIoJwtAuth, - socketIoNodeLogin, - socketIoNodeClientAsync -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3004; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) - // doesn't require login - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - - -test.cb.skip('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { - t.plan(1) - t.pass() - t.end() -}) diff --git a/packages/ws-client/tests/jwt/socketio-handshake.test.js b/packages/ws-client/tests/jwt/socketio-handshake.test.js deleted file mode 100644 index 2b0be302..00000000 --- a/packages/ws-client/tests/jwt/socketio-handshake.test.js +++ /dev/null @@ -1,133 +0,0 @@ -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -const { join } = require('path') -const fsx = require('fs-extra') -const { BASE64_FORMAT, RSA_ALGO } = require('jsonql-constants') -// import server -const { - socketIoHandshakeAuth, - jwtRsaToken, - socketIoGetUserdata, - socketIoNodeClientAsync, - socketIoNodeHandshakeLogin, - chainPromises - -} = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') -const baseDir = join(__dirname, 'fixtures', 'keys') -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3005; -const payload = {name: 'Joel'}; -const url = `http://localhost:${port}`; - -test.before( t => { - t.context.publicKey = fsx.readFileSync(join(baseDir, 'publicKey.pem')) - t.context.privateKey = fsx.readFileSync(join(baseDir, 'privateKey.pem')) - - t.context.token = jwtRsaToken(payload, t.context.privateKey); - - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - - t.context.server = server; - // setup socket.io - const io = socketIo(server) - - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoHandshakeAuth(nsp1, { - secret: Buffer.from(t.context.publicKey, BASE64_FORMAT), - algorithms: RSA_ALGO - }) - - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}); - -test.after( t => { - t.context.server.close() -}); - -test.serial.cb('It should able to connect to nsp during handshake', t => { - t.plan(4) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - nsp1.on('connection', (sock) => { - let userdata = socketIoGetUserdata(sock) - debug('nsp1 connection established', userdata) - setTimeout(() => { - sock.emit('hello2', msg) - }, 500) - sock.on('hello1', m => { - // debug('hello1', m); - t.truthy(m) // 1 - }) - }) - nsp2.on('connection', sock2 => { - sock2.on('hello', m => { - debug('hello', m) - t.is(m, 'world') // 2 - }) - }) - socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) - .then(client1 => { - client1.emit('hello1', 'WTF?') - debug('connect to nsp1 established') - client1.on('hello2', message => { - t.is(message, msg) // 3 - client1.disconnect() - t.end() - }) - // try to connect to the public nsp here - socketIoNodeClientAsync(`${url}${namespace2}`) - .then(client2 => { - debug('connect to nsp2 established') - t.truthy(client2) // 4 - client2.emit('hello', 'world') - setTimeout(() => { - client2.disconnect() - }, 500) - }) - - }) - .catch(() => { - debug('login failed!') - }) -}) - -test.serial.cb('Try to use the chain promise method with manually insert connector', t => { - t.plan(3) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - nsp1.on('connection', sock1 => { - let userdata = socketIoGetUserdata(sock1) - t.is(userdata.name, payload.name) - }) - - nsp2.on('connection', sock2 => { - sock2.on('hello', msg => { - t.is(msg, 'world') - t.end() - }) - }) - - let p1 = () => socketIoNodeHandshakeLogin(`${url}${namespace1}`, t.context.token) - let p2 = () => socketIoNodeClientAsync(`${url}${namespace2}`) - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length,2) - nsps[1].emit('hello', 'world') - }) -}) diff --git a/packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js b/packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js deleted file mode 100644 index edbd6f13..00000000 --- a/packages/ws-client/tests/jwt/socketio-roundtrip-fail.test.js +++ /dev/null @@ -1,60 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { socketIoJwtAuth, socketIoHandshakeAuth, socketIoNodeRoundtripLogin } = require('../main') -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3002; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }); - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret: 'wrong-secret' }) - - t.context.server.listen(port) -}); - -test.after( t => { - t.context.server.close() -}); - -test.cb('It should failed when we pass a wrong secret', t => { - t.plan(1) - t.context.nsp1.then( socket => { - setTimeout(() => { - socket.emit('hello', msg) - }, 500) - }) - - socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - .then(client => { - client.on('hello', message => { - t.is(message, msg) - t.end() - }) - }) - .catch(err => { - debug('did get the catch error!', err) - t.pass() - t.end() - }) - -}) diff --git a/packages/ws-client/tests/jwt/socketio-roundtrip.test.js b/packages/ws-client/tests/jwt/socketio-roundtrip.test.js deleted file mode 100644 index 6a9c498e..00000000 --- a/packages/ws-client/tests/jwt/socketio-roundtrip.test.js +++ /dev/null @@ -1,119 +0,0 @@ -// testing the socket.io auth with client and server -const test = require('ava') -const http = require('http') -const socketIo = require('socket.io') -// const socketIoClient = require('socket.io-client') -const debug = require('debug')('jsonql-jwt:test:socketio-auth') -// import server -const { - socketIoJwtAuth, - socketIoNodeRoundtripLogin, - socketIoNodeClientAsync, - socketIoGetUserdata, - chainPromises -} = require('../main') - -// import data -const { secret, token, namespace, msg } = require('./fixtures/options') - -const namespace1 = '/' + namespace + '/a'; -const namespace2 = '/' + namespace + '/b'; -const port = 3001; - -const url = `http://localhost:${port}`; - -test.before( t => { - // setup server - const server = http.createServer((req, res) => { - res.writeHead(200, {'Content-Type': 'text/plain'}) - res.write('Hello world!') - res.end() - }) - t.context.server = server; - // setup socket.io - const io = socketIo(server) - const nsp1 = io.of(namespace1) - const nsp2 = io.of(namespace2) - - t.context.nsp1 = socketIoJwtAuth(nsp1, { secret }) - // doesn't require login - t.context.nsp2 = nsp2; - - t.context.server.listen(port) -}) - -test.after( t => { - t.context.server.close() -}) - -test.serial.cb('It should able to connect using the token', t => { - t.plan(1) - t.context.nsp1.then( socket => { - setTimeout(() => { - socket.emit('hello', msg) - }, 500) - }) - - socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - .then(client => { - client.on('hello', message => { - t.is(message, msg) - client.disconnect() - t.end() - }) - }) - .catch(err => { - debug('error?', err) - }) -}) - -test.serial.cb('It should able to connect to a public namespace using the socketIoNodeClientAsync', t => { - t.plan(2) - t.context.nsp2.on('connection', socket => { - debug('connection established') - socket.on('hello', function(msg) { - t.is(msg, 'world') - socket.disconnect() - t.end() - }) - }) - socketIoNodeClientAsync([url, namespace2].join('')).then(nsp => { - t.truthy(nsp) - nsp.emit('hello', 'world') - }) -}) - -test.serial.cb('It should able to round trip connect in sequence using the chain promises', t => { - t.plan(3) - let nsp1 = t.context.nsp1; - let nsp2 = t.context.nsp2; - let p1 = () => socketIoNodeRoundtripLogin(`${url}${namespace1}`, token) - let p2 = () => socketIoNodeClientAsync([url, namespace2].join('')) - - // the jwtAuth is a promise interface - - nsp1.then(sock1 => { - let userdata = socketIoGetUserdata(sock1) - t.is(userdata.name, 'Joel', 'should able to decode the token to userdata') - //t.end() - }) - - nsp2.on('connection', sock2 => { - sock2.on('hello', msg => { - t.is(msg, 'world', 'should get the message hello world') - t.end() - }) - }) - - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length, 2, 'should return two nsps') - // send something to the public - setTimeout(() => { - nsps[1].emit('hello', 'world') - }, 500) - - }) - -}) diff --git a/packages/ws-client/tests/jwt/ws-handshake.test.js b/packages/ws-client/tests/jwt/ws-handshake.test.js deleted file mode 100644 index 9829abfd..00000000 --- a/packages/ws-client/tests/jwt/ws-handshake.test.js +++ /dev/null @@ -1,104 +0,0 @@ -// 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/ws-client/tests/ws-client-auth-login.test.js b/packages/ws-client/tests/ws-client-auth-login.test.js deleted file mode 100644 index 833dfc4d..00000000 --- a/packages/ws-client/tests/ws-client-auth-login.test.js +++ /dev/null @@ -1,103 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') - -const wsClient = require('../main') -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 } = require('jsonql-constants') -const payload = {name: 'Joel'}; - -const debug = require('debug')('jsonql-ws-client:test:ws-auth-login') - -const port = 8003; - -test.before(async t => { - - const { io, app } = await serverSetup({ - contract, - contractDir, - resolverDir: join(__dirname, 'fixtures', 'resolvers'), - serverType: 'ws', - enableAuth: true, - keysDir: join(__dirname, 'fixtures', 'keys') - }) - t.context.server = app.listen(port) - // without the token - t.context.client = await wsClient({ - serverType: 'ws', - hostname: `ws://localhost:${port}`, - contract: publicContract, - enableAuth: true, - useJwt: true - }) - -}) - -test.after(t => { - t.context.server.close() -}) -// access the public namespace - -// @BUG the login is not quite 100% yet, but we need to test this more -// in the browser, the problem is this is bi-directional and -// when we add a client to connect to the server, it could create some -// strange effects. We might have to issue an LOGOUT before we attempt to -// LOGIN to clear out all the existing connections - -test.serial.cb('It should able to connect to the ws server public namespace', t => { - let ctn = 0; - t.plan(2) - let client = t.context.client; - client.pinging('Hello') - - client.pinging.onResult= (res) => { - debug('res', res) - t.is(res, 'connection established') - client.pinging.send = 'ping'; - } - // the send is happen after the result return on the server side - client.pinging.onMessage = function(msg) { - if (msg==='pong') { - client.pinging.send = 'pong'; - } else { - client.pinging.send = 'giving up'; - debug('TEST SHOULD HALT HERE') - t.pass() - t.end() - } - } -}) - -test.serial.cb('It should trigger the login call here', t => { - t.plan(2) - let client = t.context.client; - let ctn = 0; - // add onReady and wait for the login to happen - client.onReady = function(namespace) { - debug('onReady -->', namespace, client.simple.myNamespace) - if (namespace === client.simple.myNamespace) { - client.simple(200) - client.simple.onResult = (result) => { - debug('simple onResult pass (3)', result) - t.pass() - t.end() - } - } - } - - client.simple(100) - client.simple.onError = (error) => { - if (!ctn) { - t.is(NOT_LOGIN_ERR_MSG, error.message, 'pass (2)') - const token = genToken(payload) - client.login(token) - ++ctn; - } - } -}) diff --git a/packages/ws-client/tests/ws-client-auth.test.js b/packages/ws-client/tests/ws-client-auth.test.js deleted file mode 100644 index f7961b25..00000000 --- a/packages/ws-client/tests/ws-client-auth.test.js +++ /dev/null @@ -1,94 +0,0 @@ -// standard ws client test without auth -const test = require('ava') - -const wsClient = require('../main') -const serverSetup = require('./fixtures/server-setup') - -const { join } = require('path') -const fsx = require('fs-extra') - -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 debug = require('debug')('jsonql-ws-client:test:ws-auth') - -const payload = {name: 'Joel'}; -const token = genToken(payload) -const port = 8002; - -test.before(async t => { - - const { io, app } = await serverSetup({ - contract, - contractDir, - resolverDir: join(__dirname, 'fixtures', 'resolvers'), - serverType: 'ws', - enableAuth: true, - // useJwt: true, - keysDir: join(__dirname, 'fixtures', 'keys') - }) - t.context.server = app.listen(port) - - t.context.client = await wsClient({ - token, - serverType: 'ws', - hostname: `ws://localhost:${port}`, - contract: publicContract, - enableAuth: true, - useJwt: true - }) -}) - -test.after(t => { - t.context.server.close() -}) - -test.serial.cb('It should able to connect to the WebSocket public namespace', t => { - t.plan(2) - let client = t.context.client; - client.pinging('Hello') - - client.pinging.onResult = res => { - debug('res', res) - t.is(res, 'connection established') - client.pinging.send = 'ping'; - } - // start the ping pong game - client.pinging.onMessage = function(msg) { - if (msg==='pong') { - client.pinging.send = 'pong'; - } else { - client.pinging.send = 'giving up'; - t.is(msg, 'ping') - t.end() - } - } -}) - -test.serial.cb('It should able to connect to a WebSocket private namespace', t => { - t.plan(2) - let client = t.context.client; - client.onReady = (w) => { - debug('onReady again', w) - } - - client.sendExtraMsg(100) - - client.sendExtraMsg.onResult = (result) => { - t.is(101, result) - t.end() - } - - client.sendExtraMsg.onMessage = function(num) { - t.is(102, num) - } - - client.onReady = (w) => { - debug('onReady -->', w) - return w; - } - -}) diff --git a/packages/ws-client/tests/ws-client-chain.test.js b/packages/ws-client/tests/ws-client-chain.test.js deleted file mode 100644 index 612acecc..00000000 --- a/packages/ws-client/tests/ws-client-chain.test.js +++ /dev/null @@ -1,99 +0,0 @@ -// testing the chain methods -const test = require('ava') -const { join } = require('path') -const fsx = require('fs-extra') - -const { - chainPromises, - wsNodeClient, - wsNodeAuthClient -} = require('jsonql-jwt') - - -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 } = require('jsonql-constants') - -const payload = {name: 'Joel'}; -const token = genToken(payload) - -const debug = require('debug')('jsonql-ws-client:test:ws-client-chain') - -const port = 8009; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract, - contractDir, - resolverDir: join(__dirname, 'fixtures', 'resolvers'), - serverType: 'ws', - enableAuth: true, - keysDir: join(__dirname, 'fixtures', 'keys') - }) - t.context.server = app.listen(port) - - let baseUrl = `ws://localhost:${port}`; - t.context.nsp1url = [baseUrl, 'jsonql/private'].join('/') - t.context.nsp2url = [baseUrl, 'jsonql/public'].join('/') -}) - -test.serial.cb('First test the connection individually', t => { - t.plan(2) - let ws1 = wsNodeAuthClient(t.context.nsp1url, token) - let ws2 = wsNodeClient(t.context.nsp2url) - - ws1.onopen = function() { - t.pass() - ws1.terminate() - } - - ws2.onopen = function() { - t.pass() - ws2.terminate() - t.end() - } - -}) -// @BUG whenever I wrap this code in the promise the ws just hang up -test.serial.cb.skip('Try to create a promise based ws client and using the chainPromises method to login', t => { - t.plan(1) - - let p1 = () => ( - new Promise((resolver, rejecter) => { - let ws1 = wsNodeAuthClient(nsp1url, token) - let timer; - setTimeout(() => { - rejecter() - }, 5000) - ws1.onopen = () => { - clearTimeout(timer) - resolver(ws1) - } - }) - ) - let p2 = () => ( - new Promise((resolver, rejecter) => { - let ws2 = wsNodeClient(nsp2url) - let timer; - setTimeout(() => { - rejecter() - }, 5000) - ws2.onopen = () => { - clearTimeout(timer) - resolver(ws2) - } - }) - ) - - chainPromises([p1(), p2()]) - .then(nsps => { - t.is(nsps.length, 2) - t.end() - }) - -}) diff --git a/packages/ws-client/tests/ws-client.test.js b/packages/ws-client/tests/ws-client.test.js deleted file mode 100644 index 9edcd56c..00000000 --- a/packages/ws-client/tests/ws-client.test.js +++ /dev/null @@ -1,83 +0,0 @@ -// standard ws client test without auth -const test = require('ava') -const { JS_WS_NAME } = require('jsonql-constants') -const wsClient = require('../main') -const serverSetup = require('./fixtures/server-setup') - -const { join } = require('path') -const fsx = require('fs-extra') - -const publicContract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'public-contract.json')) -const contract = fsx.readJsonSync(join(__dirname, 'fixtures', 'contract', 'contract.json')) - -const debug = require('debug')('jsonql-ws-client:test:ws') - -const port = 8001; - -test.before(async t => { - const { io, app } = await serverSetup({ - contract - }) - t.context.server = app.listen(port) - - t.context.client = await wsClient({ - hostname: `ws://localhost:${port}`, - serverType: JS_WS_NAME, - contract: publicContract - }) - -}) - -test.after(t => { - t.context.server.close() -}) - -test.cb('It should able to connect to the ws server', t => { - t.plan(2) - let client = t.context.client - - t.truthy(wsClient.CLIENT_TYPE_INFO) - - client.simple(100) - client.simple.onResult = (result) => { - t.is(101, result) - t.end() - } -}) - -test.cb('It should able to handle error', t => { - t.plan(1) - let client = t.context.client; - - client.throwError() - - client.throwError.onError = (error) => { - debug(error) - t.truthy(error) - t.end() - } -}) - -test.cb('It should able to send message back while its talking to the server', t => { - t.plan(1) - let c = 0; - let client = t.context.client; - client.continuous('Jumping') - client.continuous.onResult = (msg) => { - ++c; - debug(c) - debug('onResult', c , msg) - } - // add a event handler - client.continuous.onMessage = function(msg) { - ++c; - debug(c) - if (c === 3) { - debug(c) - client.continuous.send = 'terminate' - t.pass() - t.end() - } - debug('onMessage', c , msg) - } -}) -- Gitee From e6846812a3dc83a8f988832e06e6ce7da2f0a1ef Mon Sep 17 00:00:00 2001 From: joelchu Date: Thu, 5 Sep 2019 10:09:06 +0100 Subject: [PATCH 59/59] update the deps --- packages/ws-client/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/ws-client/package.json b/packages/ws-client/package.json index 69177958..23873ae9 100755 --- a/packages/ws-client/package.json +++ b/packages/ws-client/package.json @@ -13,7 +13,6 @@ ], "scripts": { "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", @@ -32,7 +31,7 @@ "author": "Joel Chu ", "license": "MIT", "devDependencies": { - "ava": "^2.2.0", + "ava": "^2.3.0", "fs-extra": "^8.1.0", "kefir": "^3.8.6" }, @@ -58,10 +57,11 @@ }, "dependencies": { "esm": "^3.2.25", - "jsonql-constants": "^1.7.9", - "jsonql-errors": "^1.1.1", - "jsonql-jwt": "^1.2.5", - "jsonql-params-validator": "^1.4.3", + "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": { -- Gitee