diff --git a/packages/http-client/dist/jsonql-client.cls.js b/packages/http-client/dist/jsonql-client.cls.js index 0bbbffa2e07d4ca7f35bb652b8d519ff3725ce7f..84cd882003f21b45a384ae0c06cd70f48e9345ef 100644 --- a/packages/http-client/dist/jsonql-client.cls.js +++ b/packages/http-client/dist/jsonql-client.cls.js @@ -8008,6 +8008,8 @@ }(ContractClass)); // this the core of the internal storage management + + // This class will only focus on the storage system var JsonqlBaseClient = /*@__PURE__*/(function (AuthCls) { function JsonqlBaseClient(opts) { @@ -8052,12 +8054,14 @@ var expired = args[1]; // get the endpoint index var contracts = localStore$1.get(key) || []; - constracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; var _args = [key].push(contracts); if (expired) { _args.push(expired); } - this.storeIt = _args; + if (this.opts.keepContract) { + this.storeIt = _args; + } }; /** @@ -8101,6 +8105,8 @@ /** * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point * @return {string} the end point to call */ prototypeAccessors.jsonqlEndpoint.get = function () { @@ -8123,12 +8129,9 @@ * @return {object|boolean} as described above */ prototypeAccessors.jsonqlContract.get = function () { - if (this.opts.keepContract) { - var key = this.opts.storageKey; - var contracts = localStore$1.get(key) || []; - return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; - } - return false; + var key = this.opts.storageKey; + var contracts = localStore$1.get(key) || []; + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; }; /** @@ -8146,7 +8149,7 @@ // this one store in the session store /** * get login userdata decoded jwt - * @return {object|null} + * @return {object|null} */ prototypeAccessors.jsonqlUserdata.get = function () { return sessionStore$1.get(USERDATA_TABLE) diff --git a/packages/http-client/dist/jsonql-client.cls.js.map b/packages/http-client/dist/jsonql-client.cls.js.map index e744d2fe2dd628af0f2199c29e7a830c36d6cd69..030b746f91fdf9c6f9fa1dbd16705d074785913a 100644 --- a/packages/http-client/dist/jsonql-client.cls.js.map +++ b/packages/http-client/dist/jsonql-client.cls.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-client.cls.js","sources":["../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/lib/stores/local-store.js","../src/lib/stores/session-store.js","../src/lib/stores/index.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/lodash-es/isNull.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/negate.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-async.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/src/params-api.js","../node_modules/jsonql-params-validator/index.js","../src/lib/utils.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../node_modules/jsonql-jwt/src/client/ws/ws.js","../src/lib/base/flyio.js","../src/lib/base/http-cls.js","../src/lib/base/contract-cls.js","../src/lib/base/auth-cls.js","../src/lib/base/base-cls.js","../src/lib/base/index.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/lib/ee.js","../src/lib/jsonql-api-generator.js","../src/lib/options/check-options.js","../src/lib/options/index.js","../src/jsonql-api.js","../src/jsonql-client-cls.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from 'lodash-es'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from 'lodash-es'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from 'lodash-es'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from 'lodash-es'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\nimport { isNull, trim, isUndefined } from 'lodash-es'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from 'lodash-es'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from 'lodash-es'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\n// when validaton failed\nexport default class JsonqlValidationError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj);\n return !!keys.filter(k => key === k).length;\n};\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail);\n }\n throw new JsonqlError(msg, detail);\n }\n // pass through to the next\n return result;\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from 'lodash-es'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ));\n case params[0].variable === true: // using spread syntax\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ));\n // with optional defaultValue parameters\n case args.length < params.length:\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ));\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length && params.length === 1:\n // this happens when we have those array. type\n let tmp, _type = [ DEFAULT_TYPE ];\n // we only looking at the first one, this might be a @BUG!\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n }\n // if not then we fall back to the following\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i] || { type: _type, name: '_' }\n }\n ));\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n if (p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from 'lodash-es'\n\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n // debugFn('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","// this is port back from the client to share across all projects\nimport { merge } from 'lodash-es'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:check-options-async')\n\n/**\n * Quick transform\n * @param {object} config that one\n * @param {object} appProps mutation configuration options\n * @return {object} put that arg into the args\n */\nconst configToArgs = (config, appProps) => {\n return Promise.resolve(\n prepareArgsForValidation(config, appProps)\n )\n}\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return configToArgs(config, appProps)\n .then(args1 => {\n // debugFn('args', args1)\n return runValidation(args1, cb)\n })\n // next if every thing good then pass to final merging\n .then(args2 => merge({}, args2, constProps))\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants';\nimport { checkIsArray } from '../array';\nimport checkIsBoolean from '../boolean';\nimport { isFunction, isString } from 'lodash-es';\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n};\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// craete several helper function to construct / extract the payload\n// and make sure they are all the same\nimport {\n PAYLOAD_PARAM_NAME,\n CONDITION_PARAM_NAME,\n RESOLVER_PARAM_NAME,\n QUERY_ARG_NAME\n} from 'jsonql-constants'\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport isString from './string'\nimport { checkIsArray } from './array'\nimport { checkIsObject } from './object'\n\n// make sure it's an object\nconst formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload;\n\n/**\n * Get name from the payload (ported back from jsonql-koa)\n * @param {*} payload to extract from\n * @return {string} name\n */\nexport function getNameFromPayload(payload) {\n return Object.keys(payload)[0]\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {array} [args=[]] from the ...args\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createQuery(resolverName, args = [], jsonp = false) {\n if (isString(resolverName) && checkIsArray(args)) {\n let payload = { [QUERY_ARG_NAME]: args }\n if (jsonp === true) {\n return payload;\n }\n return { [resolverName]: payload }\n }\n throw new JsonqlValidationError(`[createQuery] expect resolverName to be string and args to be array!`, { resolverName, args })\n}\n\n// string version of the above\nexport function createQueryStr(resolverName, args = [], jsonp = false) {\n return JSON.stringify(createQuery(resolverName, args, jsonp))\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {*} payload to send\n * @param {object} [condition={}] for what\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createMutation(resolverName, payload, condition = {}, jsonp = false) {\n const _payload = {\n [PAYLOAD_PARAM_NAME]: payload,\n [CONDITION_PARAM_NAME]: condition\n }\n if (jsonp === true) {\n return _payload;\n }\n if (isString(resolverName)) {\n return { [resolverName]: _payload }\n }\n throw new JsonqlValidationError(`[createMutation] expect resolverName to be string!`, { resolverName, payload, condition })\n}\n\n// string version of above\nexport function createMutationStr(resolverName, payload, condition = {}, jsonp = false) {\n return JSON.stringify(createMutation(resolverName, payload, condition, jsonp))\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getQueryFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName];\n if (args[QUERY_ARG_NAME]) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [QUERY_ARG_NAME]: args[QUERY_ARG_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * extra the payload back\n * @param {*} payload from http call\n * @return {object} resolverName and args\n */\nexport function getQueryFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getQueryFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload)\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getMutationFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName]\n if (args) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [PAYLOAD_PARAM_NAME]: args[PAYLOAD_PARAM_NAME],\n [CONDITION_PARAM_NAME]: args[CONDITION_PARAM_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * @param {object} payload\n * @return {object} resolverName, payload, conditon\n */\nexport function getMutationFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getMutationFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload)\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\nimport isInArray from './src/is-in-array'\n\nexport const inArray = isInArray;\n\nimport checkKeyInObject from './src/check-key-in-object'\n\nexport const isKeyInObject = checkKeyInObject;\n\nimport checkIsContract from './src/check-is-contract'\n\nexport const isContract = checkIsContract;\n\n// add in v1.3.0\n\nimport * as paramsApi from './src/params-api'\n\nexport const createQuery = paramsApi.createQuery;\nexport const createQueryStr = paramsApi.createQueryStr;\nexport const createMutation = paramsApi.createMutation;\nexport const createMutationStr = paramsApi.createMutationStr;\nexport const getQueryFromArgs = paramsApi.getQueryFromArgs;\nexport const getQueryFromPayload = paramsApi.getQueryFromPayload;\nexport const getMutationFromArgs = paramsApi.getMutationFromArgs;\nexport const getMutationFromPayload = paramsApi.getMutationFromPayload;\nexport const getNameFromPayload = paramsApi.getNameFromPayload;\n","// move some of the functions were in the class\n// but it just some util function should not be there\nimport debug from 'debug';\nimport { isObject, isKeyInObject } from 'jsonql-params-validator'\nimport { QUERY_NAME, MUTATION_NAME } from 'jsonql-constants'\n// since it's only use here there is no point of adding it to the constants module\n// or may be we add it back later\nexport const ENDPOINT_TABLE = 'endpoint';\nexport const USERDATA_TABLE = 'userdata';\n/**\n * reusable debug function\n * @param {string} name add to the main name\n * @return {function} debug function\n */\nexport const getDebug = name => debug('jsonql-client').extend(name)\n\n/**\n * @return {number} timestamp\n */\nexport const timestamp = () => Math.floor( Date.now() / 1000 )\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * @param {object} jsonqlInstance the init instance of jsonql client\n * @param {object} contract the static contract\n * @return {object} contract may be from server\n */\nexport const getContractFromConfig = function(jsonqlInstance, contract = {}) {\n if (isJsonqlContract(contract)) {\n return Promise.resolve(contract)\n }\n return jsonqlInstance.getContract()\n}\n\n/**\n * handle the return data\n * @param {object} result return from server\n * @return {object} strip the data part out, or if the error is presented\n */\nexport const resultHandler = result => (\n (isKeyInObject(result, 'data') && !isKeyInObject(result, 'error')) ? result.data : result\n)\n\n/**\n * make sure it's a JSONQL contract\n * @param {*} obj input\n * @return {boolean} true is OK\n */\nexport const isJsonqlContract = obj => (\n obj && isObject(obj) && (isKeyInObject(obj, QUERY_NAME) || isKeyInObject(obj, MUTATION_NAME))\n)\n","/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\nfunction polyfill (input) {\n var str = String(input).replace(/=+$/, '');\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = '';\n // get next character\n buffer = str.charAt(idx++);\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\n\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || Math.floor(Date.now() / 1000)\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// ws client using native WebSocket\nimport { JsonqlValidationError } from 'jsonql-errors';\n\nexport default function getWS() {\n switch(true) {\n case (typeof WebSocket !== 'undefined'):\n return WebSocket;\n case (typeof MozWebSocket !== 'undefined'):\n return MozWebSocket;\n // case (typeof global !== 'undefined'):\n // return global.WebSocket || global.MozWebSocket;\n case (typeof window !== 'undefined'):\n return window.WebSocket || window.MozWebSocket;\n // case (typeof self !== 'undefined'):\n // return self.WebSocket || self.MozWebSocket;\n default:\n throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!')\n }\n}\n","// import the module from a seprate module so we can change this easily\nimport Fly from 'flyio/dist/npm/fly'\n\nconst flyio = new Fly()\n\nexport default flyio\n","// base HttpClass\nimport flyio from './flyio'\nimport { createQuery, createMutation, getNameFromPayload, isObject, isString } from 'jsonql-params-validator'\nimport { merge } from 'lodash-es'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME\n} from 'jsonql-constants'\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n this.fly = flyio;\n this.opts = opts;\n this.extraHeader = {};\n // run the set debug\n this.debug()\n // console.info('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = cacheBurst()\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, {method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n console.info('request interceptor call')\n const headers = this.getHeaders();\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n console.info('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n console.info('get contract result', result)\n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { localStore } from '../stores';\nimport { timestamp, isJsonqlContract } from '../utils';\nimport HttpClass from './http-cls';\n\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * Set if we want to debug or not\n * @return {undefined} nothing\n */\n debug() {\n const key = 'debug';\n if (this.opts.debugOn) {\n localStore.set(key, 'jsonql-client*')\n } else {\n localStore.remove(key)\n }\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contract = this.readContract()\n if (contract) {\n return Promise.resolve(contract)\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isJsonqlContract(contract)) {\n return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired);\n if (!isNaN(expired) && expired > 0) {\n args.push(expired);\n }\n }\n this.jsonqlContract = contract;\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isJsonqlContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts);\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { localStore, sessionStore } from '../stores'\nimport { ENDPOINT_TABLE, USERDATA_TABLE, timestamp } from '../utils'\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray, inArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport AuthCls from './auth-cls'\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts) {\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n constracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n let _args = [key].push(contracts)\n if (expired) {\n _args.push(expired)\n }\n this.storeIt = _args;\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n // this one will use the sessionStore\n // basically we hook this onto the token store and decode it to store here\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n // bunch of getters\n\n /**\n * This also manage the index internally\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n if (this.opts.keepContract) {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false;\n }\n return false;\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n // this one store in the session store\n /**\n * get login userdata decoded jwt\n * @return {object|null} \n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// this is the new implementation without the hash key\n// only using Map and Set instead\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code.js'\n// export\nexport default class EventService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('$on', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('$on', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('$once', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('$once', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$only`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$only', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$onlyOnce`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$onlyOnce', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('$trigger', nStore)\n if (nStore.has(evt)) {\n this.logger('$trigger', evt, 'found')\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('set $done', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger(this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n /////////////////////////////\n // PRIVATE METHODS //\n /////////////////////////////\n\n /**\n * validate the event name\n * @param {string} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(evt) {\n if (typeof evt === 'string') {\n return true;\n }\n throw new Error(`event name must be string type!`)\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('run', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('takeFromStore', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('takeFromStore', content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('addToStore', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('addToStore', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('addToStore', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let store = this.lazyStore.get(evtName)\n this.logger('checkTypeInLazyStore', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('addToNormalStore', evt, type, 'add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger(`${type} can add to ${evt} store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n\nconst ee = new NBEventService()\n// output\nexport default ee\n","// Generate the resolver for developer to use\n\n// @TODO when enableAuth we need to add one extra check\n// before the resolver call make it to the core\n// which is checking the login state, if the developer\n// is calling a private method without logging in\n// then we should throw the JsonqlForbiddenError at this point\n// instead of making a round trip to the server\n\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport ee from './ee'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contract the contract\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contract) => {\n\n let obj = {query: {}, mutation: {}, auth: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.emitEvent(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.emitEvent(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.emitEvent(LOGOUT_NAME, KEY_WORD)\n }\n }\n /**\n * new method to allow retrieve the current login user data\n * @return {*} userdata\n */\n obj.userdata = () => jsonqlInstance.userdata;\n }\n // store this once again and export it\n if (obj.returnInstance) {\n obj.jsonqlClientInstance = jsonqlInstance;\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n obj.eventEmitter = ee;\n // output\n return obj;\n};\n\nexport default generator;\n","// we must ensure the user passing the correct options\n// therefore we need to validate against the properties as well\n\nimport { appProps, constProps } from './base-options'\nimport { checkConfigAsync } from 'jsonql-params-validator'\n\nexport default config => {\n let { contract } = config;\n return checkConfigAsync(config, appProps, constProps)\n .then(opts => {\n opts.contract = contract;\n return opts;\n })\n}\n","// export interface\nimport checkOptions from './check-options'\n\nexport default checkOptions\n","// this is new for the flyio and normalize the name from now on\nimport JsonqlBaseClient from './lib/base'\nimport generator from './lib/jsonql-api-generator'\nimport checkOptions from './lib/options'\nimport { getContractFromConfig } from './lib/utils'\n\n/**\n * Main interface for jsonql fetch api\n * @param {object} config\n * @return {object} jsonql client\n */\nexport default function(config = {}) {\n return checkOptions(config)\n .then(opts => (\n {\n baseClient: new JsonqlBaseClient(opts),\n opts: opts\n }\n ))\n .then( ({baseClient, opts}) => (\n getContractFromConfig(baseClient, opts.contract)\n .then(contract => generator(baseClient, opts, contract)\n )\n )\n );\n}\n","// Instead of a singleton, I should make it as a more proper class\n// this way the client will not only limited to call just one API end point\n// Also the way it's call jsonqlClient.then is not very elegant\n// instead I am going to make it like this\n// const client = new JsonqlClient(config)\n// client.ready(function(api) { /* now do your thing */ });\n\nimport jsonqlApi from './jsonql-api'\nimport { JsonqlError } from 'jsonql-errors'\n/**\n * We need the good old function as class instead of\n * the ES6 class because there is no private property\n * @param {object} config\n */\nexport default function JsonqlClient(config = {}) {\n\n const self = this;\n var queue = [];\n var _client;\n\n Object.defineProperty(self, 'client', {\n set(value) {\n _client = value;\n for (let i = 0; i < queue.length; ++i) {\n Reflect.apply(queue[i], null, [value])\n }\n queue = []; // unset the array\n },\n get() {\n return _client;\n }\n });\n\n self.ready = (fn) => {\n if (typeof fn === 'function') {\n if (_client !== undefined) {\n Reflect.apply(fn, null, [_client])\n } else {\n queue.push(fn)\n }\n return true;\n }\n throw new JsonqlError('Exepct a function pass to ready call!')\n }\n // run\n jsonqlApi(config)\n .then(client => {\n self.client = client;\n })\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;ACAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"jsonql-client.cls.js","sources":["../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/lib/stores/local-store.js","../src/lib/stores/session-store.js","../src/lib/stores/index.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/lodash-es/isNull.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/negate.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-async.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/src/params-api.js","../node_modules/jsonql-params-validator/index.js","../src/lib/utils.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../node_modules/jsonql-jwt/src/client/ws/ws.js","../src/lib/base/flyio.js","../src/lib/base/http-cls.js","../src/lib/base/contract-cls.js","../src/lib/base/auth-cls.js","../src/lib/base/base-cls.js","../src/lib/base/index.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/lib/ee.js","../src/lib/jsonql-api-generator.js","../src/lib/options/check-options.js","../src/lib/options/index.js","../src/jsonql-api.js","../src/jsonql-client-cls.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from 'lodash-es'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from 'lodash-es'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from 'lodash-es'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from 'lodash-es'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\nimport { isNull, trim, isUndefined } from 'lodash-es'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from 'lodash-es'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from 'lodash-es'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\n// when validaton failed\nexport default class JsonqlValidationError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj);\n return !!keys.filter(k => key === k).length;\n};\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail);\n }\n throw new JsonqlError(msg, detail);\n }\n // pass through to the next\n return result;\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from 'lodash-es'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ));\n case params[0].variable === true: // using spread syntax\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ));\n // with optional defaultValue parameters\n case args.length < params.length:\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ));\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length && params.length === 1:\n // this happens when we have those array. type\n let tmp, _type = [ DEFAULT_TYPE ];\n // we only looking at the first one, this might be a @BUG!\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n }\n // if not then we fall back to the following\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i] || { type: _type, name: '_' }\n }\n ));\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n if (p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from 'lodash-es'\n\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n // debugFn('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","// this is port back from the client to share across all projects\nimport { merge } from 'lodash-es'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:check-options-async')\n\n/**\n * Quick transform\n * @param {object} config that one\n * @param {object} appProps mutation configuration options\n * @return {object} put that arg into the args\n */\nconst configToArgs = (config, appProps) => {\n return Promise.resolve(\n prepareArgsForValidation(config, appProps)\n )\n}\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return configToArgs(config, appProps)\n .then(args1 => {\n // debugFn('args', args1)\n return runValidation(args1, cb)\n })\n // next if every thing good then pass to final merging\n .then(args2 => merge({}, args2, constProps))\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants';\nimport { checkIsArray } from '../array';\nimport checkIsBoolean from '../boolean';\nimport { isFunction, isString } from 'lodash-es';\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n};\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// craete several helper function to construct / extract the payload\n// and make sure they are all the same\nimport {\n PAYLOAD_PARAM_NAME,\n CONDITION_PARAM_NAME,\n RESOLVER_PARAM_NAME,\n QUERY_ARG_NAME\n} from 'jsonql-constants'\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport isString from './string'\nimport { checkIsArray } from './array'\nimport { checkIsObject } from './object'\n\n// make sure it's an object\nconst formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload;\n\n/**\n * Get name from the payload (ported back from jsonql-koa)\n * @param {*} payload to extract from\n * @return {string} name\n */\nexport function getNameFromPayload(payload) {\n return Object.keys(payload)[0]\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {array} [args=[]] from the ...args\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createQuery(resolverName, args = [], jsonp = false) {\n if (isString(resolverName) && checkIsArray(args)) {\n let payload = { [QUERY_ARG_NAME]: args }\n if (jsonp === true) {\n return payload;\n }\n return { [resolverName]: payload }\n }\n throw new JsonqlValidationError(`[createQuery] expect resolverName to be string and args to be array!`, { resolverName, args })\n}\n\n// string version of the above\nexport function createQueryStr(resolverName, args = [], jsonp = false) {\n return JSON.stringify(createQuery(resolverName, args, jsonp))\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {*} payload to send\n * @param {object} [condition={}] for what\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createMutation(resolverName, payload, condition = {}, jsonp = false) {\n const _payload = {\n [PAYLOAD_PARAM_NAME]: payload,\n [CONDITION_PARAM_NAME]: condition\n }\n if (jsonp === true) {\n return _payload;\n }\n if (isString(resolverName)) {\n return { [resolverName]: _payload }\n }\n throw new JsonqlValidationError(`[createMutation] expect resolverName to be string!`, { resolverName, payload, condition })\n}\n\n// string version of above\nexport function createMutationStr(resolverName, payload, condition = {}, jsonp = false) {\n return JSON.stringify(createMutation(resolverName, payload, condition, jsonp))\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getQueryFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName];\n if (args[QUERY_ARG_NAME]) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [QUERY_ARG_NAME]: args[QUERY_ARG_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * extra the payload back\n * @param {*} payload from http call\n * @return {object} resolverName and args\n */\nexport function getQueryFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getQueryFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload)\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getMutationFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName]\n if (args) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [PAYLOAD_PARAM_NAME]: args[PAYLOAD_PARAM_NAME],\n [CONDITION_PARAM_NAME]: args[CONDITION_PARAM_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * @param {object} payload\n * @return {object} resolverName, payload, conditon\n */\nexport function getMutationFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getMutationFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload)\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\nimport isInArray from './src/is-in-array'\n\nexport const inArray = isInArray;\n\nimport checkKeyInObject from './src/check-key-in-object'\n\nexport const isKeyInObject = checkKeyInObject;\n\nimport checkIsContract from './src/check-is-contract'\n\nexport const isContract = checkIsContract;\n\n// add in v1.3.0\n\nimport * as paramsApi from './src/params-api'\n\nexport const createQuery = paramsApi.createQuery;\nexport const createQueryStr = paramsApi.createQueryStr;\nexport const createMutation = paramsApi.createMutation;\nexport const createMutationStr = paramsApi.createMutationStr;\nexport const getQueryFromArgs = paramsApi.getQueryFromArgs;\nexport const getQueryFromPayload = paramsApi.getQueryFromPayload;\nexport const getMutationFromArgs = paramsApi.getMutationFromArgs;\nexport const getMutationFromPayload = paramsApi.getMutationFromPayload;\nexport const getNameFromPayload = paramsApi.getNameFromPayload;\n","// move some of the functions were in the class\n// but it just some util function should not be there\nimport debug from 'debug';\nimport { isObject, isKeyInObject } from 'jsonql-params-validator'\nimport { QUERY_NAME, MUTATION_NAME } from 'jsonql-constants'\n// since it's only use here there is no point of adding it to the constants module\n// or may be we add it back later\nexport const ENDPOINT_TABLE = 'endpoint';\nexport const USERDATA_TABLE = 'userdata';\n/**\n * reusable debug function\n * @param {string} name add to the main name\n * @return {function} debug function\n */\nexport const getDebug = name => debug('jsonql-client').extend(name)\n\n/**\n * @return {number} timestamp\n */\nexport const timestamp = () => Math.floor( Date.now() / 1000 )\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * @param {object} jsonqlInstance the init instance of jsonql client\n * @param {object} contract the static contract\n * @return {object} contract may be from server\n */\nexport const getContractFromConfig = function(jsonqlInstance, contract = {}) {\n if (isJsonqlContract(contract)) {\n return Promise.resolve(contract)\n }\n return jsonqlInstance.getContract()\n}\n\n/**\n * handle the return data\n * @param {object} result return from server\n * @return {object} strip the data part out, or if the error is presented\n */\nexport const resultHandler = result => (\n (isKeyInObject(result, 'data') && !isKeyInObject(result, 'error')) ? result.data : result\n)\n\n/**\n * make sure it's a JSONQL contract\n * @param {*} obj input\n * @return {boolean} true is OK\n */\nexport const isJsonqlContract = obj => (\n obj && isObject(obj) && (isKeyInObject(obj, QUERY_NAME) || isKeyInObject(obj, MUTATION_NAME))\n)\n","/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\nfunction polyfill (input) {\n var str = String(input).replace(/=+$/, '');\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = '';\n // get next character\n buffer = str.charAt(idx++);\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\n\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || Math.floor(Date.now() / 1000)\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// ws client using native WebSocket\nimport { JsonqlValidationError } from 'jsonql-errors';\n\nexport default function getWS() {\n switch(true) {\n case (typeof WebSocket !== 'undefined'):\n return WebSocket;\n case (typeof MozWebSocket !== 'undefined'):\n return MozWebSocket;\n // case (typeof global !== 'undefined'):\n // return global.WebSocket || global.MozWebSocket;\n case (typeof window !== 'undefined'):\n return window.WebSocket || window.MozWebSocket;\n // case (typeof self !== 'undefined'):\n // return self.WebSocket || self.MozWebSocket;\n default:\n throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!')\n }\n}\n","// import the module from a seprate module so we can change this easily\nimport Fly from 'flyio/dist/npm/fly'\n\nconst flyio = new Fly()\n\nexport default flyio\n","// base HttpClass\nimport flyio from './flyio'\nimport { createQuery, createMutation, getNameFromPayload, isObject, isString } from 'jsonql-params-validator'\nimport { merge } from 'lodash-es'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME\n} from 'jsonql-constants'\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n this.fly = flyio;\n this.opts = opts;\n this.extraHeader = {};\n // run the set debug\n this.debug()\n // console.info('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = cacheBurst()\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, {method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n console.info('request interceptor call')\n const headers = this.getHeaders();\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n console.info('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n console.info('get contract result', result)\n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { localStore } from '../stores';\nimport { timestamp, isJsonqlContract } from '../utils';\nimport HttpClass from './http-cls';\n\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * Set if we want to debug or not\n * @return {undefined} nothing\n */\n debug() {\n const key = 'debug';\n if (this.opts.debugOn) {\n localStore.set(key, 'jsonql-client*')\n } else {\n localStore.remove(key)\n }\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contract = this.readContract()\n if (contract) {\n return Promise.resolve(contract)\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isJsonqlContract(contract)) {\n return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired);\n if (!isNaN(expired) && expired > 0) {\n args.push(expired);\n }\n }\n this.jsonqlContract = contract;\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isJsonqlContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts);\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { localStore, sessionStore } from '../stores'\nimport { ENDPOINT_TABLE, USERDATA_TABLE, timestamp } from '../utils'\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray, inArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport AuthCls from './auth-cls'\n\n\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts) {\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n let _args = [key].push(contracts)\n if (expired) {\n _args.push(expired)\n }\n if (this.opts.keepContract) {\n this.storeIt = _args;\n }\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n // this one will use the sessionStore\n // basically we hook this onto the token store and decode it to store here\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n // bunch of getters\n\n /**\n * This also manage the index internally\n * There is NO need to store them in an array\n * because each instance contain one end point\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false;\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n // this one store in the session store\n /**\n * get login userdata decoded jwt\n * @return {object|null}\n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// this is the new implementation without the hash key\n// only using Map and Set instead\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code.js'\n// export\nexport default class EventService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('$on', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('$on', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('$once', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('$once', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$only`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$only', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$onlyOnce`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$onlyOnce', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('$trigger', nStore)\n if (nStore.has(evt)) {\n this.logger('$trigger', evt, 'found')\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('set $done', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger(this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n /////////////////////////////\n // PRIVATE METHODS //\n /////////////////////////////\n\n /**\n * validate the event name\n * @param {string} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(evt) {\n if (typeof evt === 'string') {\n return true;\n }\n throw new Error(`event name must be string type!`)\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('run', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('takeFromStore', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('takeFromStore', content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('addToStore', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('addToStore', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('addToStore', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let store = this.lazyStore.get(evtName)\n this.logger('checkTypeInLazyStore', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('addToNormalStore', evt, type, 'add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger(`${type} can add to ${evt} store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n\nconst ee = new NBEventService()\n// output\nexport default ee\n","// Generate the resolver for developer to use\n\n// @TODO when enableAuth we need to add one extra check\n// before the resolver call make it to the core\n// which is checking the login state, if the developer\n// is calling a private method without logging in\n// then we should throw the JsonqlForbiddenError at this point\n// instead of making a round trip to the server\n\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport ee from './ee'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contract the contract\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contract) => {\n\n let obj = {query: {}, mutation: {}, auth: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.emitEvent(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.emitEvent(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.emitEvent(LOGOUT_NAME, KEY_WORD)\n }\n }\n /**\n * new method to allow retrieve the current login user data\n * @return {*} userdata\n */\n obj.userdata = () => jsonqlInstance.userdata;\n }\n // store this once again and export it\n if (obj.returnInstance) {\n obj.jsonqlClientInstance = jsonqlInstance;\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n obj.eventEmitter = ee;\n // output\n return obj;\n};\n\nexport default generator;\n","// we must ensure the user passing the correct options\n// therefore we need to validate against the properties as well\n\nimport { appProps, constProps } from './base-options'\nimport { checkConfigAsync } from 'jsonql-params-validator'\n\nexport default config => {\n let { contract } = config;\n return checkConfigAsync(config, appProps, constProps)\n .then(opts => {\n opts.contract = contract;\n return opts;\n })\n}\n","// export interface\nimport checkOptions from './check-options'\n\nexport default checkOptions\n","// this is new for the flyio and normalize the name from now on\nimport JsonqlBaseClient from './lib/base'\nimport generator from './lib/jsonql-api-generator'\nimport checkOptions from './lib/options'\nimport { getContractFromConfig } from './lib/utils'\n\n/**\n * Main interface for jsonql fetch api\n * @param {object} config\n * @return {object} jsonql client\n */\nexport default function(config = {}) {\n return checkOptions(config)\n .then(opts => (\n {\n baseClient: new JsonqlBaseClient(opts),\n opts: opts\n }\n ))\n .then( ({baseClient, opts}) => (\n getContractFromConfig(baseClient, opts.contract)\n .then(contract => generator(baseClient, opts, contract)\n )\n )\n );\n}\n","// Instead of a singleton, I should make it as a more proper class\n// this way the client will not only limited to call just one API end point\n// Also the way it's call jsonqlClient.then is not very elegant\n// instead I am going to make it like this\n// const client = new JsonqlClient(config)\n// client.ready(function(api) { /* now do your thing */ });\n\nimport jsonqlApi from './jsonql-api'\nimport { JsonqlError } from 'jsonql-errors'\n/**\n * We need the good old function as class instead of\n * the ES6 class because there is no private property\n * @param {object} config\n */\nexport default function JsonqlClient(config = {}) {\n\n const self = this;\n var queue = [];\n var _client;\n\n Object.defineProperty(self, 'client', {\n set(value) {\n _client = value;\n for (let i = 0; i < queue.length; ++i) {\n Reflect.apply(queue[i], null, [value])\n }\n queue = []; // unset the array\n },\n get() {\n return _client;\n }\n });\n\n self.ready = (fn) => {\n if (typeof fn === 'function') {\n if (_client !== undefined) {\n Reflect.apply(fn, null, [_client])\n } else {\n queue.push(fn)\n }\n return true;\n }\n throw new JsonqlError('Exepct a function pass to ready call!')\n }\n // run\n jsonqlApi(config)\n .then(client => {\n self.client = client;\n })\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;ACAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/packages/http-client/dist/jsonql-client.umd.js b/packages/http-client/dist/jsonql-client.umd.js index 61a578cf610637cb62ed6bd50bc1325cf8b378bd..6f10045418b5eaf0a37a94403ada55c218868ac5 100644 --- a/packages/http-client/dist/jsonql-client.umd.js +++ b/packages/http-client/dist/jsonql-client.umd.js @@ -7728,7 +7728,7 @@ return this.fly.request( this.jsonqlEndpoint, payload, - merge({}, {method: POST, params: params }, options) + merge({}, { method: POST, params: params }, options) ) }; @@ -7811,7 +7811,14 @@ return this.request({}, {method: 'GET'}, this.contractHeader) .then(clientErrorsHandler) .then(function (result) { - console.info('get contract result', result); + console.info('144 get contract result', result); + // when refresh the window the result is different! + // @TODO need to check the Koa side about why is that + // also it should set a flag if we want the description or not + if (result.cache && result.contract) { + return result.contract; + } + // just the normal result return result }) }; @@ -7847,7 +7854,7 @@ Object.defineProperties( HttpClass.prototype, prototypeAccessors ); // all the contract related methods will be here - + // export var ContractClass = /*@__PURE__*/(function (HttpClass) { function ContractClass(opts) { HttpClass.call(this, opts); @@ -7877,9 +7884,13 @@ * @return {object} contract */ ContractClass.prototype.getContract = function getContract () { - var contract = this.readContract(); - if (contract) { - return Promise.resolve(contract) + var contracts = this.readContract(); + console.info('getContract first call', contracts); + if (contracts && Array.isArray(contracts)) { + var contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]; + if (contract) { + return Promise.resolve(contract) + } } return this.get() .then( this.storeContract.bind(this) ) @@ -7906,12 +7917,20 @@ ContractClass.prototype.storeContract = function storeContract (contract) { // first need to check if the contract is a contract if (!isJsonqlContract(contract)) { - return false; + throw new JsonqlValidationError("Contract is malformed!") + //return false; } + var args = [contract]; if (this.opts.contractExpired) { var expired = parseFloat(this.opts.contractExpired); + if (!isNaN(expired) && expired > 0) { + args.push(expired); + } } - this.jsonqlContract = contract; + // calling the setter + this.jsonqlContract = args; + // return it + console.info('storeContract return result', contract); return contract; }; @@ -8008,6 +8027,8 @@ }(ContractClass)); // this the core of the internal storage management + + // This class will only focus on the storage system var JsonqlBaseClient = /*@__PURE__*/(function (AuthCls) { function JsonqlBaseClient(opts) { @@ -8022,6 +8043,7 @@ // @TODO prototypeAccessors.storeIt.set = function (args) { + console.info('storeIt', args); // the args MUST contain [0] the key , [1] the content [2] optional expired in if (isArray$1(args) && args.length >= 2) { Reflect.apply(localStore$1.set, localStore$1, args); @@ -8048,16 +8070,19 @@ // by the time it call the save contract already been checked prototypeAccessors.jsonqlContract.set = function (args) { var key = this.opts.storageKey; + var _args = [ key ]; var contract = args[0]; var expired = args[1]; // get the endpoint index var contracts = localStore$1.get(key) || []; - constracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; - var _args = [key].push(contracts); + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + _args.push(contracts); if (expired) { _args.push(expired); } - this.storeIt = _args; + if (this.opts.keepContract) { + this.storeIt = _args; + } }; /** @@ -8101,6 +8126,8 @@ /** * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point * @return {string} the end point to call */ prototypeAccessors.jsonqlEndpoint.get = function () { @@ -8123,12 +8150,9 @@ * @return {object|boolean} as described above */ prototypeAccessors.jsonqlContract.get = function () { - if (this.opts.keepContract) { - var key = this.opts.storageKey; - var contracts = localStore$1.get(key) || []; - return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; - } - return false; + var key = this.opts.storageKey; + var contracts = localStore$1.get(key) || []; + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; }; /** @@ -8146,7 +8170,7 @@ // this one store in the session store /** * get login userdata decoded jwt - * @return {object|null} + * @return {object|null} */ prototypeAccessors.jsonqlUserdata.get = function () { return sessionStore$1.get(USERDATA_TABLE) @@ -8898,7 +8922,7 @@ return fn.apply(null, args) .then(jsonqlInstance.postLoginAction) .then(function (token) { - ee.emitEvent(ISSUER_NAME, token); + ee.$trigger(ISSUER_NAME, token); return token; }) }; @@ -8912,14 +8936,14 @@ return fn.apply(null, args) .then(jsonqlInstance.postLogoutAction) .then(function (r) { - ee.emitEvent(LOGOUT_NAME, r); + ee.$trigger(LOGOUT_NAME, r); return r; }) }; } else { obj[logoutHandlerName] = function () { jsonqlInstance.postLogoutAction(KEY_WORD); - ee.emitEvent(LOGOUT_NAME, KEY_WORD); + ee.$trigger(LOGOUT_NAME, KEY_WORD); }; } /** diff --git a/packages/http-client/dist/jsonql-client.umd.js.map b/packages/http-client/dist/jsonql-client.umd.js.map index c8d049c597d3ca5607edc7ba7c52e4137d559684..23638c982e173ab332c5ae13fdf680139544f8df 100644 --- a/packages/http-client/dist/jsonql-client.umd.js.map +++ b/packages/http-client/dist/jsonql-client.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"jsonql-client.umd.js","sources":["../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/lib/stores/local-store.js","../src/lib/stores/session-store.js","../src/lib/stores/index.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/lodash-es/isNull.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/negate.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-async.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/src/params-api.js","../node_modules/jsonql-params-validator/index.js","../src/lib/utils.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../node_modules/jsonql-jwt/src/client/ws/ws.js","../src/lib/base/flyio.js","../src/lib/base/http-cls.js","../src/lib/base/contract-cls.js","../src/lib/base/auth-cls.js","../src/lib/base/base-cls.js","../src/lib/base/index.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/lib/ee.js","../src/lib/jsonql-api-generator.js","../src/lib/options/check-options.js","../src/lib/options/index.js","../src/jsonql-api.js","../src/index.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from 'lodash-es'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from 'lodash-es'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from 'lodash-es'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from 'lodash-es'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\nimport { isNull, trim, isUndefined } from 'lodash-es'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from 'lodash-es'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from 'lodash-es'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\n// when validaton failed\nexport default class JsonqlValidationError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj);\n return !!keys.filter(k => key === k).length;\n};\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail);\n }\n throw new JsonqlError(msg, detail);\n }\n // pass through to the next\n return result;\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from 'lodash-es'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ));\n case params[0].variable === true: // using spread syntax\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ));\n // with optional defaultValue parameters\n case args.length < params.length:\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ));\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length && params.length === 1:\n // this happens when we have those array. type\n let tmp, _type = [ DEFAULT_TYPE ];\n // we only looking at the first one, this might be a @BUG!\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n }\n // if not then we fall back to the following\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i] || { type: _type, name: '_' }\n }\n ));\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n if (p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from 'lodash-es'\n\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n // debugFn('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","// this is port back from the client to share across all projects\nimport { merge } from 'lodash-es'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:check-options-async')\n\n/**\n * Quick transform\n * @param {object} config that one\n * @param {object} appProps mutation configuration options\n * @return {object} put that arg into the args\n */\nconst configToArgs = (config, appProps) => {\n return Promise.resolve(\n prepareArgsForValidation(config, appProps)\n )\n}\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return configToArgs(config, appProps)\n .then(args1 => {\n // debugFn('args', args1)\n return runValidation(args1, cb)\n })\n // next if every thing good then pass to final merging\n .then(args2 => merge({}, args2, constProps))\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants';\nimport { checkIsArray } from '../array';\nimport checkIsBoolean from '../boolean';\nimport { isFunction, isString } from 'lodash-es';\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n};\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// craete several helper function to construct / extract the payload\n// and make sure they are all the same\nimport {\n PAYLOAD_PARAM_NAME,\n CONDITION_PARAM_NAME,\n RESOLVER_PARAM_NAME,\n QUERY_ARG_NAME\n} from 'jsonql-constants'\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport isString from './string'\nimport { checkIsArray } from './array'\nimport { checkIsObject } from './object'\n\n// make sure it's an object\nconst formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload;\n\n/**\n * Get name from the payload (ported back from jsonql-koa)\n * @param {*} payload to extract from\n * @return {string} name\n */\nexport function getNameFromPayload(payload) {\n return Object.keys(payload)[0]\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {array} [args=[]] from the ...args\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createQuery(resolverName, args = [], jsonp = false) {\n if (isString(resolverName) && checkIsArray(args)) {\n let payload = { [QUERY_ARG_NAME]: args }\n if (jsonp === true) {\n return payload;\n }\n return { [resolverName]: payload }\n }\n throw new JsonqlValidationError(`[createQuery] expect resolverName to be string and args to be array!`, { resolverName, args })\n}\n\n// string version of the above\nexport function createQueryStr(resolverName, args = [], jsonp = false) {\n return JSON.stringify(createQuery(resolverName, args, jsonp))\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {*} payload to send\n * @param {object} [condition={}] for what\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createMutation(resolverName, payload, condition = {}, jsonp = false) {\n const _payload = {\n [PAYLOAD_PARAM_NAME]: payload,\n [CONDITION_PARAM_NAME]: condition\n }\n if (jsonp === true) {\n return _payload;\n }\n if (isString(resolverName)) {\n return { [resolverName]: _payload }\n }\n throw new JsonqlValidationError(`[createMutation] expect resolverName to be string!`, { resolverName, payload, condition })\n}\n\n// string version of above\nexport function createMutationStr(resolverName, payload, condition = {}, jsonp = false) {\n return JSON.stringify(createMutation(resolverName, payload, condition, jsonp))\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getQueryFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName];\n if (args[QUERY_ARG_NAME]) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [QUERY_ARG_NAME]: args[QUERY_ARG_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * extra the payload back\n * @param {*} payload from http call\n * @return {object} resolverName and args\n */\nexport function getQueryFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getQueryFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload)\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getMutationFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName]\n if (args) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [PAYLOAD_PARAM_NAME]: args[PAYLOAD_PARAM_NAME],\n [CONDITION_PARAM_NAME]: args[CONDITION_PARAM_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * @param {object} payload\n * @return {object} resolverName, payload, conditon\n */\nexport function getMutationFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getMutationFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload)\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\nimport isInArray from './src/is-in-array'\n\nexport const inArray = isInArray;\n\nimport checkKeyInObject from './src/check-key-in-object'\n\nexport const isKeyInObject = checkKeyInObject;\n\nimport checkIsContract from './src/check-is-contract'\n\nexport const isContract = checkIsContract;\n\n// add in v1.3.0\n\nimport * as paramsApi from './src/params-api'\n\nexport const createQuery = paramsApi.createQuery;\nexport const createQueryStr = paramsApi.createQueryStr;\nexport const createMutation = paramsApi.createMutation;\nexport const createMutationStr = paramsApi.createMutationStr;\nexport const getQueryFromArgs = paramsApi.getQueryFromArgs;\nexport const getQueryFromPayload = paramsApi.getQueryFromPayload;\nexport const getMutationFromArgs = paramsApi.getMutationFromArgs;\nexport const getMutationFromPayload = paramsApi.getMutationFromPayload;\nexport const getNameFromPayload = paramsApi.getNameFromPayload;\n","// move some of the functions were in the class\n// but it just some util function should not be there\nimport debug from 'debug';\nimport { isObject, isKeyInObject } from 'jsonql-params-validator'\nimport { QUERY_NAME, MUTATION_NAME } from 'jsonql-constants'\n// since it's only use here there is no point of adding it to the constants module\n// or may be we add it back later\nexport const ENDPOINT_TABLE = 'endpoint';\nexport const USERDATA_TABLE = 'userdata';\n/**\n * reusable debug function\n * @param {string} name add to the main name\n * @return {function} debug function\n */\nexport const getDebug = name => debug('jsonql-client').extend(name)\n\n/**\n * @return {number} timestamp\n */\nexport const timestamp = () => Math.floor( Date.now() / 1000 )\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * @param {object} jsonqlInstance the init instance of jsonql client\n * @param {object} contract the static contract\n * @return {object} contract may be from server\n */\nexport const getContractFromConfig = function(jsonqlInstance, contract = {}) {\n if (isJsonqlContract(contract)) {\n return Promise.resolve(contract)\n }\n return jsonqlInstance.getContract()\n}\n\n/**\n * handle the return data\n * @param {object} result return from server\n * @return {object} strip the data part out, or if the error is presented\n */\nexport const resultHandler = result => (\n (isKeyInObject(result, 'data') && !isKeyInObject(result, 'error')) ? result.data : result\n)\n\n/**\n * make sure it's a JSONQL contract\n * @param {*} obj input\n * @return {boolean} true is OK\n */\nexport const isJsonqlContract = obj => (\n obj && isObject(obj) && (isKeyInObject(obj, QUERY_NAME) || isKeyInObject(obj, MUTATION_NAME))\n)\n","/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\nfunction polyfill (input) {\n var str = String(input).replace(/=+$/, '');\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = '';\n // get next character\n buffer = str.charAt(idx++);\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\n\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || Math.floor(Date.now() / 1000)\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// ws client using native WebSocket\nimport { JsonqlValidationError } from 'jsonql-errors';\n\nexport default function getWS() {\n switch(true) {\n case (typeof WebSocket !== 'undefined'):\n return WebSocket;\n case (typeof MozWebSocket !== 'undefined'):\n return MozWebSocket;\n // case (typeof global !== 'undefined'):\n // return global.WebSocket || global.MozWebSocket;\n case (typeof window !== 'undefined'):\n return window.WebSocket || window.MozWebSocket;\n // case (typeof self !== 'undefined'):\n // return self.WebSocket || self.MozWebSocket;\n default:\n throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!')\n }\n}\n","// import the module from a seprate module so we can change this easily\nimport Fly from 'flyio/dist/npm/fly'\n\nconst flyio = new Fly()\n\nexport default flyio\n","// base HttpClass\nimport flyio from './flyio'\nimport { createQuery, createMutation, getNameFromPayload, isObject, isString } from 'jsonql-params-validator'\nimport { merge } from 'lodash-es'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME\n} from 'jsonql-constants'\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n this.fly = flyio;\n this.opts = opts;\n this.extraHeader = {};\n // run the set debug\n this.debug()\n // console.info('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = cacheBurst()\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, {method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n console.info('request interceptor call')\n const headers = this.getHeaders();\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n console.info('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n console.info('get contract result', result)\n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { localStore } from '../stores';\nimport { timestamp, isJsonqlContract } from '../utils';\nimport HttpClass from './http-cls';\n\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * Set if we want to debug or not\n * @return {undefined} nothing\n */\n debug() {\n const key = 'debug';\n if (this.opts.debugOn) {\n localStore.set(key, 'jsonql-client*')\n } else {\n localStore.remove(key)\n }\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contract = this.readContract()\n if (contract) {\n return Promise.resolve(contract)\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isJsonqlContract(contract)) {\n return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired);\n if (!isNaN(expired) && expired > 0) {\n args.push(expired);\n }\n }\n this.jsonqlContract = contract;\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isJsonqlContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts);\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { localStore, sessionStore } from '../stores'\nimport { ENDPOINT_TABLE, USERDATA_TABLE, timestamp } from '../utils'\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray, inArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport AuthCls from './auth-cls'\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts) {\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n constracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n let _args = [key].push(contracts)\n if (expired) {\n _args.push(expired)\n }\n this.storeIt = _args;\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n // this one will use the sessionStore\n // basically we hook this onto the token store and decode it to store here\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n // bunch of getters\n\n /**\n * This also manage the index internally\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n if (this.opts.keepContract) {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false;\n }\n return false;\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n // this one store in the session store\n /**\n * get login userdata decoded jwt\n * @return {object|null} \n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// this is the new implementation without the hash key\n// only using Map and Set instead\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code.js'\n// export\nexport default class EventService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('$on', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('$on', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('$once', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('$once', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$only`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$only', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$onlyOnce`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$onlyOnce', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('$trigger', nStore)\n if (nStore.has(evt)) {\n this.logger('$trigger', evt, 'found')\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('set $done', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger(this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n /////////////////////////////\n // PRIVATE METHODS //\n /////////////////////////////\n\n /**\n * validate the event name\n * @param {string} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(evt) {\n if (typeof evt === 'string') {\n return true;\n }\n throw new Error(`event name must be string type!`)\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('run', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('takeFromStore', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('takeFromStore', content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('addToStore', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('addToStore', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('addToStore', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let store = this.lazyStore.get(evtName)\n this.logger('checkTypeInLazyStore', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('addToNormalStore', evt, type, 'add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger(`${type} can add to ${evt} store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n\nconst ee = new NBEventService()\n// output\nexport default ee\n","// Generate the resolver for developer to use\n\n// @TODO when enableAuth we need to add one extra check\n// before the resolver call make it to the core\n// which is checking the login state, if the developer\n// is calling a private method without logging in\n// then we should throw the JsonqlForbiddenError at this point\n// instead of making a round trip to the server\n\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport ee from './ee'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contract the contract\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contract) => {\n\n let obj = {query: {}, mutation: {}, auth: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.emitEvent(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.emitEvent(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.emitEvent(LOGOUT_NAME, KEY_WORD)\n }\n }\n /**\n * new method to allow retrieve the current login user data\n * @return {*} userdata\n */\n obj.userdata = () => jsonqlInstance.userdata;\n }\n // store this once again and export it\n if (obj.returnInstance) {\n obj.jsonqlClientInstance = jsonqlInstance;\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n obj.eventEmitter = ee;\n // output\n return obj;\n};\n\nexport default generator;\n","// we must ensure the user passing the correct options\n// therefore we need to validate against the properties as well\n\nimport { appProps, constProps } from './base-options'\nimport { checkConfigAsync } from 'jsonql-params-validator'\n\nexport default config => {\n let { contract } = config;\n return checkConfigAsync(config, appProps, constProps)\n .then(opts => {\n opts.contract = contract;\n return opts;\n })\n}\n","// export interface\nimport checkOptions from './check-options'\n\nexport default checkOptions\n","// this is new for the flyio and normalize the name from now on\nimport JsonqlBaseClient from './lib/base'\nimport generator from './lib/jsonql-api-generator'\nimport checkOptions from './lib/options'\nimport { getContractFromConfig } from './lib/utils'\n\n/**\n * Main interface for jsonql fetch api\n * @param {object} config\n * @return {object} jsonql client\n */\nexport default function(config = {}) {\n return checkOptions(config)\n .then(opts => (\n {\n baseClient: new JsonqlBaseClient(opts),\n opts: opts\n }\n ))\n .then( ({baseClient, opts}) => (\n getContractFromConfig(baseClient, opts.contract)\n .then(contract => generator(baseClient, opts, contract)\n )\n )\n );\n}\n","// main export interface\n\n// @2019-05-09 new interface export with Fetch\nimport jsonqlApi from './jsonql-api'\nexport default jsonqlApi\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;ACAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"jsonql-client.umd.js","sources":["../node_modules/store/plugins/defaults.js","../node_modules/store/plugins/expire.js","../src/lib/stores/local-store.js","../src/lib/stores/session-store.js","../src/lib/stores/index.js","../node_modules/rollup-plugin-node-globals/src/global.js","../node_modules/lodash-es/_objectToString.js","../node_modules/lodash-es/isObjectLike.js","../node_modules/lodash-es/_arrayMap.js","../node_modules/lodash-es/isArray.js","../node_modules/lodash-es/isObject.js","../node_modules/lodash-es/identity.js","../node_modules/lodash-es/_toSource.js","../node_modules/lodash-es/_getValue.js","../node_modules/lodash-es/_apply.js","../node_modules/lodash-es/_copyArray.js","../node_modules/lodash-es/_shortOut.js","../node_modules/lodash-es/constant.js","../node_modules/lodash-es/_baseFindIndex.js","../node_modules/lodash-es/_baseIsNaN.js","../node_modules/lodash-es/_strictIndexOf.js","../node_modules/lodash-es/_isIndex.js","../node_modules/lodash-es/eq.js","../node_modules/lodash-es/isLength.js","../node_modules/lodash-es/_isPrototype.js","../node_modules/lodash-es/_baseTimes.js","../node_modules/lodash-es/stubFalse.js","../node_modules/lodash-es/_baseUnary.js","../node_modules/lodash-es/_overArg.js","../node_modules/lodash-es/_nativeKeysIn.js","../node_modules/lodash-es/_hashDelete.js","../node_modules/lodash-es/_listCacheClear.js","../node_modules/lodash-es/_isKeyable.js","../node_modules/lodash-es/_arrayPush.js","../node_modules/lodash-es/_baseSlice.js","../node_modules/lodash-es/_hasUnicode.js","../node_modules/lodash-es/_asciiToArray.js","../node_modules/lodash-es/_unicodeToArray.js","../node_modules/lodash-es/_stackDelete.js","../node_modules/lodash-es/_stackGet.js","../node_modules/lodash-es/_stackHas.js","../node_modules/lodash-es/_arrayFilter.js","../node_modules/lodash-es/stubArray.js","../node_modules/lodash-es/_setCacheAdd.js","../node_modules/lodash-es/_setCacheHas.js","../node_modules/lodash-es/_arraySome.js","../node_modules/lodash-es/_cacheHas.js","../node_modules/lodash-es/_mapToArray.js","../node_modules/lodash-es/_setToArray.js","../node_modules/lodash-es/_matchesStrictComparable.js","../node_modules/lodash-es/_baseHasIn.js","../node_modules/lodash-es/_baseProperty.js","../node_modules/lodash-es/_createBaseFor.js","../node_modules/lodash-es/_safeGet.js","../node_modules/lodash-es/_baseFindKey.js","../node_modules/lodash-es/isNull.js","../node_modules/lodash-es/isUndefined.js","../node_modules/lodash-es/negate.js","../node_modules/jsonql-params-validator/src/not-empty.js","../node_modules/jsonql-params-validator/src/number.js","../node_modules/jsonql-params-validator/src/string.js","../node_modules/jsonql-params-validator/src/boolean.js","../node_modules/jsonql-params-validator/src/any.js","../node_modules/jsonql-params-validator/src/constants.js","../node_modules/jsonql-params-validator/src/combine.js","../node_modules/jsonql-params-validator/src/array.js","../node_modules/jsonql-params-validator/src/object.js","../node_modules/jsonql-errors/src/500-error.js","../node_modules/jsonql-errors/src/enum-error.js","../node_modules/jsonql-errors/src/type-error.js","../node_modules/jsonql-errors/src/checker-error.js","../node_modules/jsonql-errors/src/validation-error.js","../node_modules/jsonql-errors/src/server-error.js","../node_modules/jsonql-errors/src/index.js","../node_modules/jsonql-errors/src/client-errors-handler.js","../node_modules/jsonql-params-validator/src/validator.js","../node_modules/jsonql-params-validator/src/is-in-array.js","../node_modules/jsonql-params-validator/src/options/run-validation.js","../node_modules/jsonql-params-validator/src/options/check-options-async.js","../node_modules/jsonql-params-validator/src/options/construct-config.js","../node_modules/jsonql-params-validator/src/options/index.js","../node_modules/jsonql-params-validator/src/params-api.js","../node_modules/jsonql-params-validator/index.js","../src/lib/utils.js","../node_modules/jwt-decode/lib/atob.js","../node_modules/jsonql-jwt/src/client/decode-token/decode-token.js","../node_modules/jsonql-jwt/src/client/ws/ws.js","../src/lib/base/flyio.js","../src/lib/base/http-cls.js","../src/lib/base/contract-cls.js","../src/lib/base/auth-cls.js","../src/lib/base/base-cls.js","../src/lib/base/index.js","../node_modules/nb-event-service/src/hash-code.js","../node_modules/nb-event-service/src/event-service.js","../node_modules/nb-event-service/index.js","../src/lib/ee.js","../src/lib/jsonql-api-generator.js","../src/lib/options/check-options.js","../src/lib/options/index.js","../src/jsonql-api.js","../src/index.js"],"sourcesContent":["module.exports = defaultsPlugin\n\nfunction defaultsPlugin() {\n\tvar defaultValues = {}\n\t\n\treturn {\n\t\tdefaults: defaults,\n\t\tget: get\n\t}\n\t\n\tfunction defaults(_, values) {\n\t\tdefaultValues = values\n\t}\n\t\n\tfunction get(super_fn, key) {\n\t\tvar val = super_fn()\n\t\treturn (val !== undefined ? val : defaultValues[key])\n\t}\n}\n","var namespace = 'expire_mixin'\n\nmodule.exports = expirePlugin\n\nfunction expirePlugin() {\n\tvar expirations = this.createStore(this.storage, null, this._namespacePrefix+namespace)\n\t\n\treturn {\n\t\tset: expire_set,\n\t\tget: expire_get,\n\t\tremove: expire_remove,\n\t\tgetExpiration: getExpiration,\n\t\tremoveExpiredKeys: removeExpiredKeys\n\t}\n\t\n\tfunction expire_set(super_fn, key, val, expiration) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.set(key, expiration)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_get(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\t_checkExpiration.call(this, key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction expire_remove(super_fn, key) {\n\t\tif (!this.hasNamespace(namespace)) {\n\t\t\texpirations.remove(key)\n\t\t}\n\t\treturn super_fn()\n\t}\n\t\n\tfunction getExpiration(_, key) {\n\t\treturn expirations.get(key)\n\t}\n\t\n\tfunction removeExpiredKeys(_) {\n\t\tvar keys = []\n\t\tthis.each(function(val, key) {\n\t\t\tkeys.push(key)\n\t\t})\n\t\tfor (var i=0; i true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n","/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n","/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n","/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n","/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n","/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n","/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n","/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n","/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n return string.split('');\n}\n\nexport default asciiToArray;\n","/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n","/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n","/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n","/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n","/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n","/**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\nfunction baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n}\n\nexport default baseFindKey;\n","/**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\nfunction isNull(value) {\n return value === null;\n}\n\nexport default isNull;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\nfunction negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n}\n\nexport default negate;\n","/**\n * Check several parameter that there is something in the param\n * @param {*} param input\n * @return {boolean}\n */\nimport { trim, isArray } from 'lodash-es'\n\nexport default a => {\n if (isArray(a)) {\n return true;\n }\n return a !== undefined && a !== null && trim(a) !== '';\n}\n","// validator numbers\n// import { NUMBER_TYPES } from './constants';\nimport { isNaN, isString } from 'lodash-es'\n/**\n * @2015-05-04 found a problem if the value is a number like string\n * it will pass, so add a check if it's string before we pass to next\n * @param {number} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsNumber = function(value) {\n return isString(value) ? false : !isNaN( parseFloat(value) )\n}\n\nexport default checkIsNumber\n","// validate string type\nimport { isString, trim } from 'lodash-es'\n/**\n * @param {string} value expected value\n * @return {boolean} true if OK\n */\nconst checkIsString = function(value) {\n return (trim(value) !== '') ? isString(value) : false;\n}\n\nexport default checkIsString;\n","// check for boolean\nimport { isBoolean } from 'lodash-es'\n/**\n * @param {boolean} value expected\n * @return {boolean} true if OK\n */\nconst checkIsBoolean = function(value) {\n return isBoolean(value);\n};\n\nexport default checkIsBoolean\n","// validate any thing only check if there is something\nimport { isNull, trim, isUndefined } from 'lodash-es'\n/**\n * @param {*} value the value\n * @param {boolean} [checkNull=true] strict check if there is null value\n * @return {boolean} true is OK\n */\nconst checkIsAny = function(value, checkNull = true) {\n if (!isUndefined(value) && value !== '' && trim(value) !== '') {\n if (checkNull === false || (checkNull === true && !isNull(value))) {\n return true;\n }\n }\n return false;\n};\n\nexport default checkIsAny\n","// Good practice rule - No magic number\n\nexport const ARGS_NOT_ARRAY_ERR = `args is not an array! You might want to do: ES6 Array.from(arguments) or ES5 Array.prototype.slice.call(arguments)`;\nexport const PARAMS_NOT_ARRAY_ERR = `params is not an array! Did something gone wrong when you generate the contract.json?`;\nexport const EXCEPTION_CASE_ERR = 'Could not understand your arguments and parameter structure!';\nexport const UNUSUAL_CASE_ERR = 'This is an unusual situation where the arguments are more than the params, but not mark as spread';\n\n// re-export\nimport * as JSONQL_CONSTANTS from 'jsonql-constants';\n// @TODO the jsdoc return array. and we should also allow array syntax\nexport const DEFAULT_TYPE = JSONQL_CONSTANTS.DEFAULT_TYPE;\nexport const ARRAY_TYPE_LFT = JSONQL_CONSTANTS.ARRAY_TYPE_LFT;\nexport const ARRAY_TYPE_RGT = JSONQL_CONSTANTS.ARRAY_TYPE_RGT;\n\nexport const TYPE_KEY = JSONQL_CONSTANTS.TYPE_KEY;\nexport const OPTIONAL_KEY = JSONQL_CONSTANTS.OPTIONAL_KEY;\nexport const ENUM_KEY = JSONQL_CONSTANTS.ENUM_KEY;\nexport const ARGS_KEY = JSONQL_CONSTANTS.ARGS_KEY;\nexport const CHECKER_KEY = JSONQL_CONSTANTS.CHECKER_KEY;\nexport const ALIAS_KEY = JSONQL_CONSTANTS.ALIAS_KEY;\n\nexport const ARRAY_TYPE = JSONQL_CONSTANTS.ARRAY_TYPE;\nexport const OBJECT_TYPE = JSONQL_CONSTANTS.OBJECT_TYPE;\nexport const STRING_TYPE = JSONQL_CONSTANTS.STRING_TYPE;\nexport const BOOLEAN_TYPE = JSONQL_CONSTANTS.BOOLEAN_TYPE;\nexport const NUMBER_TYPE = JSONQL_CONSTANTS.NUMBER_TYPE;\nexport const KEY_WORD = JSONQL_CONSTANTS.KEY_WORD;\nexport const OR_SEPERATOR = JSONQL_CONSTANTS.OR_SEPERATOR;\n\n// not actually in use\n// export const NUMBER_TYPES = JSONQL_CONSTANTS.NUMBER_TYPES;\n","// primitive types\nimport checkIsNumber from './number'\nimport checkIsString from './string'\nimport checkIsBoolean from './boolean'\nimport checkIsAny from './any'\nimport { NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE } from './constants'\n\n/**\n * this is a wrapper method to call different one based on their type\n * @param {string} type to check\n * @return {function} a function to handle the type\n */\nconst combineFn = function(type) {\n switch (type) {\n case NUMBER_TYPE:\n return checkIsNumber;\n case STRING_TYPE:\n return checkIsString;\n case BOOLEAN_TYPE:\n return checkIsBoolean;\n default:\n return checkIsAny;\n }\n}\n\nexport default combineFn\n","// validate array type\nimport { isArray, trim } from 'lodash-es'\nimport combineFn from './combine'\nimport {\n ARRAY_TYPE_LFT,\n ARRAY_TYPE_RGT,\n OR_SEPERATOR\n} from './constants'\n\n/**\n * @param {array} value expected\n * @param {string} [type=''] pass the type if we encounter array. then we need to check the value as well\n * @return {boolean} true if OK\n */\nexport const checkIsArray = function(value, type='') {\n if (isArray(value)) {\n if (type === '' || trim(type)==='') {\n return true;\n }\n // we test it in reverse\n // @TODO if the type is an array (OR) then what?\n // we need to take into account this could be an array\n const c = value.filter(v => !combineFn(type)(v))\n return !(c.length > 0)\n }\n return false;\n}\n\n/**\n * check if it matches the array. pattern\n * @param {string} type\n * @return {boolean|array} false means NO, always return array\n */\nexport const isArrayLike = function(type) {\n // @TODO could that have something like array<> instead of array.<>? missing the dot?\n // because type script is Array without the dot\n if (type.indexOf(ARRAY_TYPE_LFT) > -1 && type.indexOf(ARRAY_TYPE_RGT) > -1) {\n const _type = type.replace(ARRAY_TYPE_LFT, '').replace(ARRAY_TYPE_RGT, '')\n if (_type.indexOf(OR_SEPERATOR)) {\n return _type.split(OR_SEPERATOR)\n }\n return [_type]\n }\n return false;\n}\n\n/**\n * we might encounter something like array. then we need to take it apart\n * @param {object} p the prepared object for processing\n * @param {string|array} type the type came from \n * @return {boolean} for the filter to operate on\n */\nexport const arrayTypeHandler = function(p, type) {\n const { arg } = p;\n // need a special case to handle the OR type\n // we need to test the args instead of the type(s)\n if (type.length > 1) {\n return !arg.filter(v => (\n !(type.length > type.filter(t => !combineFn(t)(v)).length)\n )).length;\n }\n // type is array so this will be or!\n return type.length > type.filter(t => !checkIsArray(arg, t)).length;\n}\n","// validate object type\nimport { isPlainObject, isUndefined, filter } from 'lodash-es'\nimport combineFn from './combine'\nimport { checkIsArray, isArrayLike, arrayTypeHandler } from './array'\n/**\n * @TODO if provide with the keys then we need to check if the key:value type as well\n * @param {object} value expected\n * @param {array} [keys=null] if it has the keys array to compare as well\n * @return {boolean} true if OK\n */\nexport const checkIsObject = function(value, keys=null) {\n if (isPlainObject(value)) {\n if (!keys) {\n return true;\n }\n if (checkIsArray(keys)) {\n // please note we DON'T care if some is optional\n // plese refer to the contract.json for the keys\n return !keys.filter(key => {\n let _value = value[key.name];\n return !(key.type.length > key.type.filter(type => {\n let tmp;\n if (!isUndefined(_value)) {\n if ((tmp = isArrayLike(type)) !== false) {\n return !arrayTypeHandler({arg: _value}, tmp)\n // return tmp.filter(t => !checkIsArray(_value, t)).length;\n // @TODO there might be an object within an object with keys as well :S\n }\n return !combineFn(type)(_value)\n }\n return true;\n }).length)\n }).length;\n }\n }\n return false;\n}\n\n/**\n * fold this into it's own function to handler different object type\n * @param {object} p the prepared object for process\n * @return {boolean}\n */\nexport const objectTypeHandler = function(p) {\n const { arg, param } = p;\n let _args = [arg];\n if (Array.isArray(param.keys) && param.keys.length) {\n _args.push(param.keys)\n }\n // just simple check\n return checkIsObject.apply(null, _args)\n}\n","/**\n * This is a custom error to throw when server throw a 500\n * This help us to capture the right error, due to the call happens in sequence\n * @param {string} message to tell what happen\n * @param {mixed} extra things we want to add, 500?\n */\nexport default class Jsonql500Error extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = Jsonql500Error.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, Jsonql500Error);\n }\n }\n\n static get statusCode() {\n return 500;\n }\n\n static get name() {\n return 'Jsonql500Error';\n }\n\n}\n","// this get throw from within the checkOptions when run through the enum failed\nexport default class JsonqlEnumError extends Error {\n constructor(...args) {\n super(...args);\n \n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlEnumError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlEnumError);\n }\n }\n\n static get name() {\n return 'JsonqlEnumError';\n }\n}\n","// this will throw from inside the checkOptions\nexport default class JsonqlTypeError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlTypeError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlTypeError);\n }\n }\n\n static get name() {\n return 'JsonqlTypeError';\n }\n}\n","// allow supply a custom checker function\n// if that failed then we throw this error\nexport default class JsonqlCheckerError extends Error {\n constructor(...args) {\n super(...args);\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlCheckerError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlCheckerError);\n }\n }\n\n static get name() {\n return 'JsonqlCheckerError';\n }\n}\n","// custom validation error class\n// when validaton failed\nexport default class JsonqlValidationError extends Error {\n constructor(...args) {\n super(...args);\n\n this.message = args[0];\n this.detail = args[1];\n\n this.className = JsonqlValidationError.name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, JsonqlValidationError);\n }\n }\n\n static get name() {\n return 'JsonqlValidationError';\n }\n}\n","// this is from an example from Koa team to use for internal middleware ctx.throw\n// but after the test the res.body part is unable to extract the required data\n// I keep this one here for future reference\n\nexport default class JsonqlServerError extends Error {\n\n constructor(statusCode, message) {\n super(message);\n this.statusCode = statusCode;\n this.className = JsonqlServerError.name;\n }\n\n static get name() {\n return 'JsonqlServerError';\n }\n}\n","// server side\nimport Jsonql406Error from './406-error';\nimport Jsonql500Error from './500-error';\nimport JsonqlAuthorisationError from './authorisation-error';\nimport JsonqlContractAuthError from './contract-auth-error';\nimport JsonqlResolverAppError from './resolver-app-error';\nimport JsonqlResolverNotFoundError from './resolver-not-found-error';\n// check options error\nimport JsonqlEnumError from './enum-error';\nimport JsonqlTypeError from './type-error';\nimport JsonqlCheckerError from './checker-error';\n// share\nimport JsonqlValidationError from './validation-error';\nimport JsonqlError from './error';\n\nimport JsonqlServerError from './server-error';\n\nexport {\n Jsonql406Error,\n Jsonql500Error,\n JsonqlAuthorisationError,\n JsonqlContractAuthError,\n JsonqlResolverAppError,\n JsonqlResolverNotFoundError,\n\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError,\n\n JsonqlValidationError,\n JsonqlError,\n\n JsonqlServerError\n};\n","// this will add directly to the then call in each http call\n\nimport * as errors from './index';\nimport getErrorByStatus from './get-error-by-status';\nimport { NO_ERROR_MSG } from 'jsonql-constants';\nconst { JsonqlError } = errors;\n\n/**\n * We can not just check something like result.data what if the result if false?\n * @param {object} obj the result object\n * @param {string} key we want to check if its exist or not\n * @return {boolean} true on found\n */\nconst isKeyInObject = (obj, key) => {\n const keys = Object.keys(obj);\n return !!keys.filter(k => key === k).length;\n};\n\n/**\n * It will ONLY have our own jsonql specific implement check\n * @param {object} result the server return result\n * @return {object} this will just throw error\n */\nexport default function clientErrorsHandler(result) {\n if (isKeyInObject(result, 'error')) {\n const { error } = result;\n const { className, name } = error;\n const errorName = className || name;\n // just throw the whole thing back\n const msg = error.message || NO_ERROR_MSG;\n const detail = error.detail || error;\n if (errorName && errors[errorName]) {\n throw new errors[className](msg, detail);\n }\n throw new JsonqlError(msg, detail);\n }\n // pass through to the next\n return result;\n}\n","// move the index.js code here that make more sense to find where things are\nimport { isUndefined } from 'lodash-es'\nimport {\n checkIsArray,\n isArrayLike,\n arrayTypeHandler,\n objectTypeHandler,\n checkIsObject,\n combineFn,\n notEmpty\n} from './index'\nimport {\n DEFAULT_TYPE,\n ARRAY_TYPE,\n OBJECT_TYPE,\n ARGS_NOT_ARRAY_ERR,\n PARAMS_NOT_ARRAY_ERR,\n EXCEPTION_CASE_ERR,\n UNUSUAL_CASE_ERR\n} from './constants'\nimport { DATA_KEY, ERROR_KEY } from 'jsonql-constants'\nimport { JsonqlError } from 'jsonql-errors'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:validator')\n// also export this for use in other places\n\n/**\n * We need to handle those optional parameter without a default value\n * @param {object} params from contract.json\n * @return {boolean} for filter operation false is actually OK\n */\nconst optionalHandler = function( params ) {\n const { arg, param } = params;\n if (notEmpty(arg)) {\n // debug('call optional handler', arg, params);\n // loop through the type in param\n return !(param.type.length > param.type.filter(type =>\n validateHandler(type, params)\n ).length)\n }\n return false;\n}\n\n/**\n * actually picking the validator\n * @param {*} type for checking\n * @param {*} value for checking\n * @return {boolean} true on OK\n */\nconst validateHandler = function(type, value) {\n let tmp;\n switch (true) {\n case type === OBJECT_TYPE:\n // debugFn('call OBJECT_TYPE')\n return !objectTypeHandler(value)\n case type === ARRAY_TYPE:\n // debugFn('call ARRAY_TYPE')\n return !checkIsArray(value.arg)\n // @TODO when the type is not present, it always fall through here\n // so we need to find a way to actually pre-check the type first\n // AKA check the contract.json map before running here\n case (tmp = isArrayLike(type)) !== false:\n // debugFn('call ARRAY_LIKE: %O', value)\n return !arrayTypeHandler(value, tmp)\n default:\n return !combineFn(type)(value.arg)\n }\n}\n\n/**\n * it get too longer to fit in one line so break it out from the fn below\n * @param {*} arg value\n * @param {object} param config\n * @return {*} value or apply default value\n */\nconst getOptionalValue = function(arg, param) {\n if (!isUndefined(arg)) {\n return arg;\n }\n return (param.optional === true && !isUndefined(param.defaultvalue) ? param.defaultvalue : null)\n}\n\n/**\n * padding the arguments with defaultValue if the arguments did not provide the value\n * this will be the name export\n * @param {array} args normalized arguments\n * @param {array} params from contract.json\n * @return {array} merge the two together\n */\nexport const normalizeArgs = function(args, params) {\n // first we should check if this call require a validation at all\n // there will be situation where the function doesn't need args and params\n if (!checkIsArray(params)) {\n // debugFn('params value', params)\n throw new JsonqlError(PARAMS_NOT_ARRAY_ERR)\n }\n if (params.length === 0) {\n return [];\n }\n if (!checkIsArray(args)) {\n throw new JsonqlError(ARGS_NOT_ARRAY_ERR)\n }\n // debugFn(args, params);\n // fall through switch\n switch(true) {\n case args.length == params.length: // standard\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i]\n }\n ));\n case params[0].variable === true: // using spread syntax\n const type = params[0].type;\n return args.map((arg, i) => (\n {\n arg,\n index: i, // keep the index for reference\n param: params[i] || { type, name: '_' }\n }\n ));\n // with optional defaultValue parameters\n case args.length < params.length:\n return params.map((param, i) => (\n {\n param,\n index: i,\n arg: getOptionalValue(args[i], param),\n optional: param.optional || false\n }\n ));\n // this one pass more than it should have anything after the args.length will be cast as any type\n case args.length > params.length && params.length === 1:\n // this happens when we have those array. type\n let tmp, _type = [ DEFAULT_TYPE ];\n // we only looking at the first one, this might be a @BUG!\n if ((tmp = isArrayLike(params[0].type[0])) !== false) {\n _type = tmp;\n }\n // if not then we fall back to the following\n return args.map((arg, i) => (\n {\n arg,\n index: i,\n param: params[i] || { type: _type, name: '_' }\n }\n ));\n // @TODO find out if there is more cases not cover\n default: // this should never happen\n // debugFn('args', args)\n // debugFn('params', params)\n // this is unknown therefore we just throw it!\n throw new JsonqlError(EXCEPTION_CASE_ERR, { args, params })\n }\n}\n\n// what we want is after the validaton we also get the normalized result\n// which is with the optional property if the argument didn't provide it\n/**\n * process the array of params back to their arguments\n * @param {array} result the params result\n * @return {array} arguments\n */\nconst processReturn = result => result.map(r => r.arg)\n\n/**\n * validator main interface\n * @param {array} args the arguments pass to the method call\n * @param {array} params from the contract for that method\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {array} empty array on success, or failed parameter and reasons\n */\nexport const validateSync = function(args, params, withResult = false) {\n let cleanArgs = normalizeArgs(args, params)\n let checkResult = cleanArgs.filter(p => {\n if (p.param.optional === true) {\n return optionalHandler(p)\n }\n // because array of types means OR so if one pass means pass\n return !(p.param.type.length > p.param.type.filter(\n type => validateHandler(type, p)\n ).length)\n })\n // using the same convention we been using all this time\n return !withResult ? checkResult : {\n [ERROR_KEY]: checkResult,\n [DATA_KEY]: processReturn(cleanArgs)\n }\n}\n\n/**\n * A wrapper method that return promise\n * @param {array} args arguments\n * @param {array} params from contract.json\n * @param {boolean} [withResul=false] if true then this will return the normalize result as well\n * @return {object} promise.then or catch\n */\nexport const validateAsync = function(args, params, withResult = false) {\n return new Promise((resolver, rejecter) => {\n const result = validateSync(args, params, withResult)\n if (withResult) {\n return result[ERROR_KEY].length ? rejecter(result[ERROR_KEY])\n : resolver(result[DATA_KEY])\n }\n // the different is just in the then or catch phrase\n return result.length ? rejecter(result) : resolver([])\n })\n}\n","/**\n * @param {array} arr Array for check\n * @param {*} value target\n * @return {boolean} true on successs\n */\nconst isInArray = function(arr, value) {\n return !!arr.filter(a => a === value).length;\n}\n\nexport default isInArray\n","// breaking the whole thing up to see what cause the multiple calls issue\n\nimport { isFunction, merge, mapValues } from 'lodash-es'\n\nimport {\n TYPE_KEY,\n OPTIONAL_KEY,\n ENUM_KEY,\n ARGS_KEY,\n CHECKER_KEY,\n KEY_WORD\n} from '../constants'\nimport {\n JsonqlEnumError,\n JsonqlTypeError,\n JsonqlCheckerError\n} from 'jsonql-errors'\nimport { checkIsArray } from '../array'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:validation')\n\n/**\n * just make sure it returns an array to use\n * @param {*} arg input\n * @return {array} output\n */\nconst toArray = arg => checkIsArray(arg) ? arg : [arg]\n\n/**\n * DIY in array\n * @param {array} arr to check against\n * @param {*} value to check\n * @return {boolean} true on OK\n */\nconst inArray = (arr, value) => (\n !!arr.filter(v => v === value).length\n)\n\n/**\n * break out to make the code easier to read\n * @param {object} value to process\n * @param {function} cb the validateSync\n * @return {array} empty on success\n */\nfunction validateHandler(value, cb) {\n // cb is the validateSync methods\n let args = [\n [ value[ARGS_KEY] ],\n [{\n [TYPE_KEY]: toArray(value[TYPE_KEY]),\n [OPTIONAL_KEY]: value[OPTIONAL_KEY]\n }]\n ]\n // debugFn('validateHandler', args)\n return Reflect.apply(cb, null, args)\n}\n\n/**\n * Check against the enum value if it's provided\n * @param {*} value to check\n * @param {*} enumv to check against if it's not false\n * @return {boolean} true on OK\n */\nconst enumHandler = (value, enumv) => {\n if (checkIsArray(enumv)) {\n return inArray(enumv, value)\n }\n return true;\n}\n\n/**\n * Allow passing a function to check the value\n * There might be a problem here if the function is incorrect\n * and that will makes it hard to debug what is going on inside\n * @TODO there could be a few feature add to this one under different circumstance\n * @param {*} value to check\n * @param {function} checker for checking\n */\nconst checkerHandler = (value, checker) => {\n try {\n return isFunction(checker) ? checker.apply(null, [value]) : false;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Taken out from the runValidaton this only validate the required values\n * @param {array} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {array} of configuration values\n */\nfunction runValidationAction(cb) {\n return (value, key) => {\n // debugFn('runValidationAction', key, value)\n if (value[KEY_WORD]) {\n return value[ARGS_KEY]\n }\n const check = validateHandler(value, cb)\n if (check.length) {\n // debugFn('runValidationAction', key, value)\n throw new JsonqlTypeError(key, check)\n }\n if (value[ENUM_KEY] !== false && !enumHandler(value[ARGS_KEY], value[ENUM_KEY])) {\n throw new JsonqlEnumError(key)\n }\n if (value[CHECKER_KEY] !== false && !checkerHandler(value[ARGS_KEY], value[CHECKER_KEY])) {\n throw new JsonqlCheckerError(key)\n }\n return value[ARGS_KEY]\n }\n}\n\n/**\n * @param {object} args from the config2argsAction\n * @param {function} cb validateSync\n * @return {object} of configuration values\n */\nexport default function runValidation(args, cb) {\n const [ argsForValidate, pristineValues ] = args;\n // turn the thing into an array and see what happen here\n // debugFn('_args', argsForValidate)\n const result = mapValues(argsForValidate, runValidationAction(cb))\n return merge(result, pristineValues)\n}\n","// this is port back from the client to share across all projects\nimport { merge } from 'lodash-es'\nimport { prepareArgsForValidation } from './prepare-args-for-validation'\nimport runValidation from './run-validation'\n\n// import debug from 'debug'\n// const debugFn = debug('jsonql-params-validator:check-options-async')\n\n/**\n * Quick transform\n * @param {object} config that one\n * @param {object} appProps mutation configuration options\n * @return {object} put that arg into the args\n */\nconst configToArgs = (config, appProps) => {\n return Promise.resolve(\n prepareArgsForValidation(config, appProps)\n )\n}\n\n/**\n * @param {object} config user provide configuration option\n * @param {object} appProps mutation configuration options\n * @param {object} constProps the immutable configuration options\n * @param {function} cb the validateSync method\n * @return {object} Promise resolve merge config object\n */\nexport default function(config = {}, appProps, constProps, cb) {\n return configToArgs(config, appProps)\n .then(args1 => {\n // debugFn('args', args1)\n return runValidation(args1, cb)\n })\n // next if every thing good then pass to final merging\n .then(args2 => merge({}, args2, constProps))\n}\n","// create function to construct the config entry so we don't need to keep building object\nimport {\n ARGS_KEY,\n TYPE_KEY,\n CHECKER_KEY,\n ENUM_KEY,\n OPTIONAL_KEY,\n ALIAS_KEY\n} from 'jsonql-constants';\nimport { checkIsArray } from '../array';\nimport checkIsBoolean from '../boolean';\nimport { isFunction, isString } from 'lodash-es';\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:construct-config');\n/**\n * @param {*} args value\n * @param {string} type for value\n * @param {boolean} [optional=false]\n * @param {boolean|array} [enumv=false]\n * @param {boolean|function} [checker=false]\n * @return {object} config entry\n */\nexport default function(args, type, optional=false, enumv=false, checker=false, alias=false) {\n let base = {\n [ARGS_KEY]: args,\n [TYPE_KEY]: type\n };\n if (optional === true) {\n base[OPTIONAL_KEY] = true;\n }\n if (checkIsArray(enumv)) {\n base[ENUM_KEY] = enumv;\n }\n if (isFunction(checker)) {\n base[CHECKER_KEY] = checker;\n }\n if (isString(alias)) {\n base[ALIAS_KEY] = alias;\n }\n return base;\n};\n","// export also create wrapper methods\nimport checkOptionsAsync from './check-options-async'\nimport checkOptionsSync from './check-options-sync'\nimport constructConfigFn from './construct-config'\nimport {\n ENUM_KEY,\n CHECKER_KEY,\n ALIAS_KEY,\n OPTIONAL_KEY\n} from 'jsonql-constants'\n\n// import debug from 'debug';\n// const debugFn = debug('jsonql-params-validator:options:index');\n\n/**\n * This has a different interface\n * @param {*} value to supply\n * @param {string|array} type for checking\n * @param {object} params to map against the config check\n * @param {array} params.enumv NOT enum\n * @param {boolean} params.optional false then nothing\n * @param {function} params.checker need more work on this one later\n * @param {string} params.alias mostly for cmd\n */\nconst createConfig = (value, type, params = {}) => {\n // Note the enumv not ENUM\n // const { enumv, optional, checker, alias } = params;\n // let args = [value, type, optional, enumv, checker, alias];\n const {\n [OPTIONAL_KEY]: o,\n [ENUM_KEY]: e,\n [CHECKER_KEY]: c,\n [ALIAS_KEY]: a\n } = params;\n return constructConfigFn.apply(null, [value, type, o, e, c, a])\n}\n\n// for testing purpose\nconst JSONQL_PARAMS_VALIDATOR_INFO = '__PLACEHOLDER__';\n\n/**\n * We recreate the method here to avoid the circlar import\n * @param {object} config user supply configuration\n * @param {object} appProps mutation options\n * @param {object} [constantProps={}] optional: immutation options\n * @return {object} all checked configuration\n */\nconst checkConfigAsync = function(validateSync) {\n return function(config, appProps, constantProps= {}) {\n return checkOptionsAsync(config, appProps, constantProps, validateSync)\n }\n}\n\n// copy of above but it's sync\nconst checkConfig = function(validateSync) {\n return function(config, appProps, constantProps = {}) {\n return checkOptionsSync(config, appProps, constantProps, validateSync)\n }\n}\n\n// re-export\nexport {\n createConfig,\n constructConfigFn,\n checkConfigAsync,\n checkConfig,\n JSONQL_PARAMS_VALIDATOR_INFO\n}\n","// craete several helper function to construct / extract the payload\n// and make sure they are all the same\nimport {\n PAYLOAD_PARAM_NAME,\n CONDITION_PARAM_NAME,\n RESOLVER_PARAM_NAME,\n QUERY_ARG_NAME\n} from 'jsonql-constants'\nimport { JsonqlValidationError } from 'jsonql-errors'\n\nimport isString from './string'\nimport { checkIsArray } from './array'\nimport { checkIsObject } from './object'\n\n// make sure it's an object\nconst formatPayload = payload => isString(payload) ? JSON.parse(payload) : payload;\n\n/**\n * Get name from the payload (ported back from jsonql-koa)\n * @param {*} payload to extract from\n * @return {string} name\n */\nexport function getNameFromPayload(payload) {\n return Object.keys(payload)[0]\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {array} [args=[]] from the ...args\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createQuery(resolverName, args = [], jsonp = false) {\n if (isString(resolverName) && checkIsArray(args)) {\n let payload = { [QUERY_ARG_NAME]: args }\n if (jsonp === true) {\n return payload;\n }\n return { [resolverName]: payload }\n }\n throw new JsonqlValidationError(`[createQuery] expect resolverName to be string and args to be array!`, { resolverName, args })\n}\n\n// string version of the above\nexport function createQueryStr(resolverName, args = [], jsonp = false) {\n return JSON.stringify(createQuery(resolverName, args, jsonp))\n}\n\n/**\n * @param {string} resolverName name of function\n * @param {*} payload to send\n * @param {object} [condition={}] for what\n * @param {boolean} [jsonp = false] add v1.3.0 to koa\n * @return {object} formatted argument\n */\nexport function createMutation(resolverName, payload, condition = {}, jsonp = false) {\n const _payload = {\n [PAYLOAD_PARAM_NAME]: payload,\n [CONDITION_PARAM_NAME]: condition\n }\n if (jsonp === true) {\n return _payload;\n }\n if (isString(resolverName)) {\n return { [resolverName]: _payload }\n }\n throw new JsonqlValidationError(`[createMutation] expect resolverName to be string!`, { resolverName, payload, condition })\n}\n\n// string version of above\nexport function createMutationStr(resolverName, payload, condition = {}, jsonp = false) {\n return JSON.stringify(createMutation(resolverName, payload, condition, jsonp))\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getQueryFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName];\n if (args[QUERY_ARG_NAME]) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [QUERY_ARG_NAME]: args[QUERY_ARG_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * extra the payload back\n * @param {*} payload from http call\n * @return {object} resolverName and args\n */\nexport function getQueryFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getQueryFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getQueryArgs] Payload is malformed!', payload)\n}\n\n/**\n * Further break down from method below for use else where\n * @param {string} resolverName name of fn\n * @param {object} payload payload\n * @return {object|boolean} false on failed\n */\nexport function getMutationFromArgs(resolverName, payload) {\n if (resolverName && checkIsObject(payload)) {\n const args = payload[resolverName]\n if (args) {\n return {\n [RESOLVER_PARAM_NAME]: resolverName,\n [PAYLOAD_PARAM_NAME]: args[PAYLOAD_PARAM_NAME],\n [CONDITION_PARAM_NAME]: args[CONDITION_PARAM_NAME]\n }\n }\n }\n return false;\n}\n\n/**\n * @param {object} payload\n * @return {object} resolverName, payload, conditon\n */\nexport function getMutationFromPayload(payload) {\n const p = formatPayload(payload);\n const resolverName = getNameFromPayload(p)\n const result = getMutationFromArgs(resolverName, p)\n if (result !== false) {\n return result;\n }\n throw new JsonqlValidationError('[getMutationArgs] Payload is malformed!', payload)\n}\n","// export\nimport {\n checkIsObject,\n notEmpty,\n checkIsAny,\n checkIsString,\n checkIsBoolean,\n checkIsNumber,\n checkIsArray\n} from './src'\n// PIA syntax\nexport const isObject = checkIsObject;\nexport const isAny = checkIsAny;\nexport const isString = checkIsString;\nexport const isBoolean = checkIsBoolean;\nexport const isNumber = checkIsNumber;\nexport const isArray = checkIsArray;\nexport const isNotEmpty = notEmpty;\n\nimport * as validator from './src/validator'\n\nexport const normalizeArgs = validator.normalizeArgs;\nexport const validateSync = validator.validateSync;\nexport const validateAsync = validator.validateAsync;\n\n// configuration checking\n\nimport * as jsonqlOptions from './src/options'\n\nexport const JSONQL_PARAMS_VALIDATOR_INFO = jsonqlOptions.JSONQL_PARAMS_VALIDATOR_INFO;\n\nexport const createConfig = jsonqlOptions.createConfig;\nexport const constructConfig = jsonqlOptions.constructConfigFn;\n\nexport const checkConfigAsync = jsonqlOptions.checkConfigAsync(validator.validateSync)\nexport const checkConfig = jsonqlOptions.checkConfig(validator.validateSync)\n\nimport isInArray from './src/is-in-array'\n\nexport const inArray = isInArray;\n\nimport checkKeyInObject from './src/check-key-in-object'\n\nexport const isKeyInObject = checkKeyInObject;\n\nimport checkIsContract from './src/check-is-contract'\n\nexport const isContract = checkIsContract;\n\n// add in v1.3.0\n\nimport * as paramsApi from './src/params-api'\n\nexport const createQuery = paramsApi.createQuery;\nexport const createQueryStr = paramsApi.createQueryStr;\nexport const createMutation = paramsApi.createMutation;\nexport const createMutationStr = paramsApi.createMutationStr;\nexport const getQueryFromArgs = paramsApi.getQueryFromArgs;\nexport const getQueryFromPayload = paramsApi.getQueryFromPayload;\nexport const getMutationFromArgs = paramsApi.getMutationFromArgs;\nexport const getMutationFromPayload = paramsApi.getMutationFromPayload;\nexport const getNameFromPayload = paramsApi.getNameFromPayload;\n","// move some of the functions were in the class\n// but it just some util function should not be there\nimport debug from 'debug';\nimport { isObject, isKeyInObject } from 'jsonql-params-validator'\nimport { QUERY_NAME, MUTATION_NAME } from 'jsonql-constants'\n// since it's only use here there is no point of adding it to the constants module\n// or may be we add it back later\nexport const ENDPOINT_TABLE = 'endpoint';\nexport const USERDATA_TABLE = 'userdata';\n/**\n * reusable debug function\n * @param {string} name add to the main name\n * @return {function} debug function\n */\nexport const getDebug = name => debug('jsonql-client').extend(name)\n\n/**\n * @return {number} timestamp\n */\nexport const timestamp = () => Math.floor( Date.now() / 1000 )\n\n/**\n * construct a url with query parameters\n * @param {string} url to append\n * @param {object} params to append to url\n * @return {string} url with appended params\n */\nexport const urlParams = (url, params) => {\n let parts = [];\n for (let key in params) {\n parts.push(\n [key, params[key]].join('=')\n );\n }\n return [url, parts.join('&')].join('?')\n}\n\n/**\n * @param {string} url to append to\n * @return {object} _cb key timestamp\n */\nexport const cacheBurstUrl = url => urlParams(url, cacheBurst())\n\nexport const cacheBurst = () => ({ _cb: timestamp() })\n\n/**\n * @param {object} jsonqlInstance the init instance of jsonql client\n * @param {object} contract the static contract\n * @return {object} contract may be from server\n */\nexport const getContractFromConfig = function(jsonqlInstance, contract = {}) {\n if (isJsonqlContract(contract)) {\n return Promise.resolve(contract)\n }\n return jsonqlInstance.getContract()\n}\n\n/**\n * handle the return data\n * @param {object} result return from server\n * @return {object} strip the data part out, or if the error is presented\n */\nexport const resultHandler = result => (\n (isKeyInObject(result, 'data') && !isKeyInObject(result, 'error')) ? result.data : result\n)\n\n/**\n * make sure it's a JSONQL contract\n * @param {*} obj input\n * @return {boolean} true is OK\n */\nexport const isJsonqlContract = obj => (\n obj && isObject(obj) && (isKeyInObject(obj, QUERY_NAME) || isKeyInObject(obj, MUTATION_NAME))\n)\n","/**\n * The code was extracted from:\n * https://github.com/davidchambers/Base64.js\n */\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\nfunction InvalidCharacterError(message) {\n this.message = message;\n}\n\nInvalidCharacterError.prototype = new Error();\nInvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\nfunction polyfill (input) {\n var str = String(input).replace(/=+$/, '');\n if (str.length % 4 == 1) {\n throw new InvalidCharacterError(\"'atob' failed: The string to be decoded is not correctly encoded.\");\n }\n for (\n // initialize result and counters\n var bc = 0, bs, buffer, idx = 0, output = '';\n // get next character\n buffer = str.charAt(idx++);\n // character found in table? initialize bit storage and add its ascii value;\n ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n // and if not first of each 4 characters,\n // convert the first 8 bits to one ascii character\n bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n ) {\n // try to find character in table (0-63, not found => -1)\n buffer = chars.indexOf(buffer);\n }\n return output;\n}\n\n\nmodule.exports = typeof window !== 'undefined' && window.atob && window.atob.bind(window) || polyfill;\n","// when the user is login with the jwt\n// we use call this to decode the token and then add the payload\n// to the resolver so the user can call ResolverName.userdata\n// and get back the payload\nimport jwt_decode from 'jwt-decode'\nimport { isString } from 'jsonql-params-validator'\nimport { JsonqlError } from 'jsonql-errors'\n\n/**\n * We only check the nbf and exp\n * @param {object} token for checking\n * @return {object} token on success\n */\nfunction validate(token) {\n const start = token.iat || Math.floor(Date.now() / 1000)\n // we only check the exp for the time being\n if (token.exp) {\n if (start >= token.exp) {\n const expired = new Date(token.exp).toISOString()\n throw new JsonqlError(`Token has expired on ${expired}`, token)\n }\n }\n return token;\n}\n\n/**\n * The browser client version it has far fewer options and it doesn't verify it\n * because it couldn't this is the job for the server\n * @TODO we need to add some extra proessing here to check for the exp field\n * @param {string} token to decrypted\n * @return {object} decrypted object\n */\nexport default function jwtDecode(token) {\n if (isString(token)) {\n const t = jwt_decode(token)\n return validate(t)\n }\n throw new JsonqlError('Token must be a string!')\n}\n","// ws client using native WebSocket\nimport { JsonqlValidationError } from 'jsonql-errors';\n\nexport default function getWS() {\n switch(true) {\n case (typeof WebSocket !== 'undefined'):\n return WebSocket;\n case (typeof MozWebSocket !== 'undefined'):\n return MozWebSocket;\n // case (typeof global !== 'undefined'):\n // return global.WebSocket || global.MozWebSocket;\n case (typeof window !== 'undefined'):\n return window.WebSocket || window.MozWebSocket;\n // case (typeof self !== 'undefined'):\n // return self.WebSocket || self.MozWebSocket;\n default:\n throw new JsonqlValidationError('WebSocket is NOT SUPPORTED!')\n }\n}\n","// import the module from a seprate module so we can change this easily\nimport Fly from 'flyio/dist/npm/fly'\n\nconst flyio = new Fly()\n\nexport default flyio\n","// base HttpClass\nimport flyio from './flyio'\nimport { createQuery, createMutation, getNameFromPayload, isObject, isString } from 'jsonql-params-validator'\nimport { merge } from 'lodash-es'\nimport {\n JsonqlValidationError,\n JsonqlServerError,\n clientErrorsHandler\n} from 'jsonql-errors'\nimport {\n cacheBurst,\n urlParams,\n resultHandler\n} from '../utils'\nimport {\n API_REQUEST_METHODS,\n DEFAULT_HEADER,\n JSONP_CALLBACK_NAME\n} from 'jsonql-constants'\n// extract the one we need\nconst [ POST, PUT ] = API_REQUEST_METHODS\n\nexport default class HttpClass {\n /**\n * The opts has been check at the init stage\n * @param {object} opts configuration options\n */\n constructor(opts) {\n this.fly = flyio;\n this.opts = opts;\n this.extraHeader = {};\n // run the set debug\n this.debug()\n // console.info('start up opts', opts);\n this.reqInterceptor()\n this.resInterceptor()\n }\n\n // set headers for that one call\n set headers(header) {\n this.extraHeader = header;\n }\n\n /**\n * Create the reusage request method\n * @param {object} payload jsonql payload\n * @param {object} options extra options add the request\n * @param {object} headers extra headers add to the call\n * @return {object} the fly request instance\n */\n request(payload, options = {}, headers = {}) {\n this.headers = headers;\n let params = cacheBurst()\n // @TODO need to add a jsonp url and payload\n if (this.opts.enableJsonp) {\n let resolverName = getNameFromPayload(payload)\n params = merge({}, params, {[JSONP_CALLBACK_NAME]: resolverName})\n payload = payload[resolverName]\n }\n return this.fly.request(\n this.jsonqlEndpoint,\n payload,\n merge({}, { method: POST, params }, options)\n )\n }\n\n /**\n * This will replace the create baseRequest method\n *\n */\n reqInterceptor() {\n this.fly.interceptors.request.use(\n req => {\n console.info('request interceptor call')\n const headers = this.getHeaders();\n for (let key in headers) {\n req.headers[key] = headers[key];\n }\n return req;\n }\n )\n }\n\n // @TODO\n processJsonp(result) {\n return resultHandler(result)\n }\n\n /**\n * This will be replacement of the first then call\n *\n */\n resInterceptor() {\n const self = this;\n const jsonp = self.opts.enableJsonp;\n this.fly.interceptors.response.use(\n res => {\n console.info('response interceptor call')\n self.cleanUp()\n // now more processing here\n // there is a problem if we throw the result.error here\n // the original data is lost, so we need to do what we did before\n // deal with that error in the first then instead\n const result = isString(res.data) ? JSON.parse(res.data) : res.data;\n if (jsonp) {\n return self.processJsonp(result)\n }\n return resultHandler(result)\n },\n // this get call when it's not 200\n err => {\n self.cleanUp()\n console.error(err)\n throw new JsonqlServerError('Server side error', err)\n }\n )\n }\n\n /**\n * Get the headers inject into the call\n * @return {object} headers\n */\n getHeaders() {\n if (this.opts.enableAuth) {\n return merge({}, DEFAULT_HEADER, this.getAuthHeader(), this.extraHeader)\n }\n return merge({}, DEFAULT_HEADER, this.extraHeader)\n }\n\n /**\n * Post http call operation to clean up things we need\n */\n cleanUp() {\n this.extraHeader = {}\n }\n\n /**\n * GET for contract only\n */\n get() {\n return this.request({}, {method: 'GET'}, this.contractHeader)\n .then(clientErrorsHandler)\n .then(result => {\n console.info('144 get contract result', result)\n // when refresh the window the result is different!\n // @TODO need to check the Koa side about why is that\n // also it should set a flag if we want the description or not\n if (result.cache && result.contract) {\n return result.contract;\n }\n // just the normal result \n return result\n })\n }\n\n /**\n * POST to server - query\n * @param {object} name of the resolver\n * @param {array} args arguments\n * @return {object} promise resolve to the resolver return\n */\n query(name, args = []) {\n return this.request(createQuery(name, args))\n .then(clientErrorsHandler)\n }\n\n /**\n * PUT to server - mutation\n * @param {string} name of resolver\n * @param {object} payload what it said\n * @param {object} conditions what it said\n * @return {object} promise resolve to the resolver return\n */\n mutation(name, payload = {}, conditions = {}) {\n return this.request(createMutation(name, payload, conditions), {method: PUT})\n .then(clientErrorsHandler)\n }\n\n}\n","// all the contract related methods will be here\nimport { localStore } from '../stores';\nimport { ENDPOINT_TABLE, timestamp, isJsonqlContract } from '../utils';\nimport HttpClass from './http-cls';\nimport { JsonqlValidationError } from 'jsonql-errors'\n// export\nexport default class ContractClass extends HttpClass {\n\n constructor(opts) {\n super(opts)\n }\n\n /**\n * Set if we want to debug or not\n * @return {undefined} nothing\n */\n debug() {\n const key = 'debug';\n if (this.opts.debugOn) {\n localStore.set(key, 'jsonql-client*')\n } else {\n localStore.remove(key)\n }\n }\n\n /**\n * return the contract public api\n * @return {object} contract\n */\n getContract() {\n const contracts = this.readContract()\n console.info('getContract first call', contracts)\n if (contracts && Array.isArray(contracts)) {\n const contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ]\n if (contract) {\n return Promise.resolve(contract)\n }\n }\n return this.get()\n .then( this.storeContract.bind(this) )\n }\n\n /**\n * We are changing the way how to auth to get the contract.json\n * Instead of in the url, we will be putting that key value in the header\n * @return {object} header\n */\n get contractHeader() {\n let base = {};\n if (this.opts.contractKey !== false) {\n base[this.opts.contractKeyName] = this.opts.contractKey;\n }\n return base;\n }\n\n /**\n * Save the contract to local store\n * @param {object} contract to save\n * @return {object|boolean} false when its not a contract or contract on OK\n */\n storeContract(contract) {\n // first need to check if the contract is a contract\n if (!isJsonqlContract(contract)) {\n throw new JsonqlValidationError(`Contract is malformed!`)\n //return false;\n }\n let args = [contract]\n if (this.opts.contractExpired) {\n let expired = parseFloat(this.opts.contractExpired)\n if (!isNaN(expired) && expired > 0) {\n args.push(expired)\n }\n }\n // calling the setter\n this.jsonqlContract = args;\n // return it\n console.info('storeContract return result', contract)\n return contract;\n }\n\n /**\n * return the contract from options or localStore\n * @return {object} contract\n */\n readContract() {\n let contract = isJsonqlContract(this.opts.contract)\n return contract ? this.opts.contract : localStore.get(this.opts.storageKey)\n }\n}\n","// this is the new auth class that integrate with the jsonql-jwt\n// all the auth related methods will be here\nimport { decodeToken } from 'jsonql-jwt'\nimport {\n CREDENTIAL_STORAGE_KEY,\n AUTH_HEADER,\n BEARER\n} from 'jsonql-constants'\n// chain\nimport ContractClass from './contract-cls'\n// export\nexport default class AuthClass extends ContractClass {\n\n constructor(opts) {\n super(opts);\n if (opts.enableAuth && opts.useJwt) {\n this.setDecoder = decodeToken;\n }\n }\n\n /**\n * Getter to get the login userdata\n * @return {mixed} userdata\n */\n get userdata() {\n return this.jsonqlUserdata; // see base-cls\n }\n\n /**\n * Return the token from session store\n * @return {string} token\n */\n get rawAuthToken() {\n // this should return from the base\n return this.jsonqlToken; // see base-cls\n }\n\n /**\n * Setter to add a decoder when retrieve user token\n * @param {function} d a decoder\n */\n set setDecoder(d) {\n if (typeof d === 'function') {\n this.decoder = d;\n }\n }\n\n /**\n * Setter after login success\n * @TODO this move to a new class to handle multiple login\n * @param {string} token to store\n * @return {*} success store\n */\n storeToken(token) {\n return this.jsonqlToken = token;\n }\n\n /**\n * for overwrite\n * @param {string} token stored token\n * @return {string} token\n */\n decoder(token) {\n return token;\n }\n\n /**\n * Construct the auth header\n * @return {object} header\n */\n getAuthHeader() {\n const token = this.rawAuthToken;\n return token ? {[this.opts.AUTH_HEADER]: `${BEARER} ${token}`} : {};\n }\n\n}\n","// this the core of the internal storage management\nimport { localStore, sessionStore } from '../stores'\nimport { ENDPOINT_TABLE, USERDATA_TABLE, timestamp } from '../utils'\nimport { CREDENTIAL_STORAGE_KEY } from 'jsonql-constants'\nimport { isObject, isArray, inArray } from 'jsonql-params-validator'\nimport { JsonqlValidationError } from 'jsonql-errors'\n// chaining into the classes\nimport AuthCls from './auth-cls'\n\n\n// This class will only focus on the storage system\nexport default class JsonqlBaseClient extends AuthCls {\n\n constructor(opts) {\n super(opts)\n }\n\n // @TODO\n set storeIt(args) {\n console.info('storeIt', args)\n // the args MUST contain [0] the key , [1] the content [2] optional expired in\n if (isArray(args) && args.length >= 2) {\n Reflect.apply(localStore.set, localStore, args)\n }\n throw new JsonqlValidationError(`Expect argument to be array and least 2 items!`)\n }\n\n // this table index key will drive the contract\n // also it should not allow to change dynamicly\n // because this is how different client can id itself\n // OK this could be self manage because when init a new client\n // it will add a new endpoint and we will know if they are the same or not\n // but the check here\n set jsonqlEndpoint(endpoint) {\n let urls = localStore.get(ENDPOINT_TABLE) || []\n // should check if this url already existed?\n if (!inArray(urls, endpoint)) {\n urls.push(endpoint)\n this.storeId = [ENDPOINT_TABLE, urls]\n this[ENDPOINT_TABLE + 'Index'] = urls.length - 1;\n }\n }\n\n // by the time it call the save contract already been checked\n set jsonqlContract(args) {\n const key = this.opts.storageKey;\n let _args = [ key ]\n let [ contract, expired ] = args;\n // get the endpoint index\n let contracts = localStore.get(key) || []\n contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract;\n _args.push(contracts)\n if (expired) {\n _args.push(expired)\n }\n if (this.opts.keepContract) {\n this.storeIt = _args;\n }\n }\n\n /**\n * save token\n * @param {string} token to store\n * @return {string|boolean} false on failed\n */\n set jsonqlToken(token) {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key) || []\n if (!inArray(tokens, token)) {\n let index = tokens.length - 1;\n tokens[ index ] = token;\n this[key + 'Index'] = index;\n let args = [key, tokens]\n if (this.opts.tokenExpired) {\n const expired = parseFloat(this.opts.tokenExpired)\n if (!isNaN(expired) && expired > 0) {\n const ts = timestamp()\n args.push( ts + parseFloat(expired) )\n }\n }\n this.storeIt = args;\n // now decode it and store in the userdata\n this.jsonqlUserdata = this.decoder(token)\n return token;\n }\n return false;\n }\n // this one will use the sessionStore\n // basically we hook this onto the token store and decode it to store here\n set jsonqlUserdata(userdata) {\n const args = [USERDATA_TABLE, userdata]\n if (userdata.exp) {\n args.push(userdata.exp)\n }\n return Reflect.apply(localStore.set, localStore, args)\n }\n\n // bunch of getters\n\n /**\n * This also manage the index internally\n * There is NO need to store them in an array\n * because each instance contain one end point\n * @return {string} the end point to call\n */\n get jsonqlEndpoint() {\n let urls = localStore.get(ENDPOINT_TABLE)\n if (!urls) {\n const { hostname, jsonqlPath } = this.opts;\n let url = [hostname, jsonqlPath].join('/')\n this.jsonqlEndpoint = url;\n return url;\n }\n return urls[this[ENDPOINT_TABLE + 'Index']]\n }\n\n /**\n * If already stored then return it by the end point index\n * or false when there is none\n * 1.2.0 start using the keepContract option (replace the useLocalStorage)\n * @return {object|boolean} as described above\n */\n get jsonqlContract() {\n const key = this.opts.storageKey\n let contracts = localStore.get(key) || []\n return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false;\n }\n\n /**\n * Jsonql token getter\n * @return {string|boolean} false when failed\n */\n get jsonqlToken() {\n const key = CREDENTIAL_STORAGE_KEY;\n let tokens = localStorage.get(key)\n if (tokens) {\n return tokens[ this[key + 'Index'] ]\n }\n return false;\n }\n // this one store in the session store\n /**\n * get login userdata decoded jwt\n * @return {object|null}\n */\n get jsonqlUserdata() {\n return sessionStore.get(USERDATA_TABLE)\n }\n\n}\n","// export interface\n// @public\nimport JsonqlBaseClient from './base-cls'\n\nexport default JsonqlBaseClient\n","/**\n * generate a 32bit hash based on the function.toString()\n * _from http://stackoverflow.com/questions/7616461/generate-a-hash-_from-string-in-javascript-jquery\n * @param {string} s the converted to string function\n * @return {string} the hashed function string\n */\nexport default function hashCode(s) {\n\treturn s.split(\"\").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0)\n}\n","// this is the new implementation without the hash key\n// only using Map and Set instead\nimport {\n NB_EVENT_SERVICE_PRIVATE_STORE,\n NB_EVENT_SERVICE_PRIVATE_LAZY\n} from './store'\nimport genHaskKey from './hash-code.js'\n// export\nexport default class EventService {\n /**\n * class constructor\n */\n constructor(config = {}) {\n if (config.logger && typeof config.logger === 'function') {\n this.logger = config.logger;\n }\n this.keep = config.keep;\n // for the $done setter\n this.result = config.keep ? [] : null;\n // we need to init the store first otherwise it could be a lot of checking later\n this.normalStore = new Map()\n this.lazyStore = new Map()\n }\n\n /**\n * logger function for overwrite\n */\n logger() {}\n\n //////////////////////////\n // PUBLIC METHODS //\n //////////////////////////\n\n /**\n * Register your evt handler, note we don't check the type here,\n * we expect you to be sensible and know what you are doing.\n * @param {string} evt name of event\n * @param {function} callback bind method --> if it's array or not\n * @param {object} [context=null] to execute this call in\n * @return {number} the size of the store\n */\n $on(evt , callback , context = null) {\n const type = 'on';\n this.validate(evt, callback)\n // first need to check if this evt is in lazy store\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register first then call later\n if (lazyStoreContent === false) {\n this.logger('$on', `${evt} callback is not in lazy store`)\n // @TODO we need to check if there was other listener to this\n // event and are they the same type then we could solve that\n // register the different type to the same event name\n\n return this.addToNormalStore(evt, type, callback, context)\n }\n this.logger('$on', `${evt} found in lazy store`)\n // this is when they call $trigger before register this callback\n let size = 0;\n lazyStoreContent.forEach(content => {\n let [ payload, ctx, t ] = content;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n size += this.addToNormalStore(evt, type, callback, context || ctx)\n })\n return size;\n }\n\n /**\n * once only registered it once, there is no overwrite option here\n * @NOTE change in v1.3.0 $once can add multiple listeners\n * but once the event fired, it will remove this event (see $only)\n * @param {string} evt name\n * @param {function} callback to execute\n * @param {object} [context=null] the handler execute in\n * @return {boolean} result\n */\n $once(evt , callback , context = null) {\n this.validate(evt, callback)\n const type = 'once';\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (lazyStoreContent === false) {\n this.logger('$once', `${evt} not in the lazy store`)\n // v1.3.0 $once now allow to add multiple listeners\n return this.addToNormalStore(evt, type, callback, context)\n } else {\n // now this is the tricky bit\n // there is a potential bug here that cause by the developer\n // if they call $trigger first, the lazy won't know it's a once call\n // so if in the middle they register any call with the same evt name\n // then this $once call will be fucked - add this to the documentation\n this.logger('$once', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n }\n\n /**\n * This one event can only bind one callbackback\n * @param {string} evt event name\n * @param {function} callback event handler\n * @param {object} [context=null] the context the event handler execute in\n * @return {boolean} true bind for first time, false already existed\n */\n $only(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'only';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$only`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$only', `${evt} found data in lazy store to execute`)\n const list = Array.from(lazyStoreContent)\n // $only allow to trigger this multiple time on the single handler\n list.forEach( l => {\n const [ payload, ctx, t ] = l;\n if (t && t !== type) {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n })\n }\n return added;\n }\n\n /**\n * $only + $once this is because I found a very subtile bug when we pass a\n * resolver, rejecter - and it never fire because that's OLD adeed in v1.4.0\n * @param {string} evt event name\n * @param {function} callback to call later\n * @param {object} [context=null] exeucte context\n * @return {void}\n */\n $onlyOnce(evt, callback, context = null) {\n this.validate(evt, callback)\n const type = 'onlyOnce';\n let added = false;\n let lazyStoreContent = this.takeFromStore(evt)\n // this is normal register before call $trigger\n let nStore = this.normalStore;\n if (!nStore.has(evt)) {\n this.logger(`$onlyOnce`, `${evt} add to store`)\n added = this.addToNormalStore(evt, type, callback, context)\n }\n if (lazyStoreContent !== false) {\n // there are data store in lazy store\n this.logger('$onlyOnce', lazyStoreContent)\n const list = Array.from(lazyStoreContent)\n // should never have more than 1\n const [ payload, ctx, t ] = list[0]\n if (t && t !== 'onlyOnce') {\n throw new Error(`You are trying to register an event already been taken by other type: ${t}`)\n }\n this.run(callback, payload, context || ctx)\n // remove this evt from store\n this.$off(evt)\n }\n return added;\n }\n\n /**\n * This is a shorthand of $off + $on added in V1.5.0\n * @param {string} evt event name\n * @param {function} callback to exeucte\n * @param {object} [context = null] or pass a string as type\n * @param {string} [type=on] what type of method to replace\n * @return {}\n */\n $replace(evt, callback, context = null, type = 'on') {\n if (this.validateType(type)) {\n this.$off(evt)\n let method = this['$' + type]\n return Reflect.apply(method, this, [evt, callback, context])\n }\n throw new Error(`${type} is not supported!`)\n }\n\n /**\n * trigger the event\n * @param {string} evt name NOT allow array anymore!\n * @param {mixed} [payload = []] pass to fn\n * @param {object|string} [context = null] overwrite what stored\n * @param {string} [type=false] if pass this then we need to add type to store too\n * @return {number} if it has been execute how many times\n */\n $trigger(evt , payload = [] , context = null, type = false) {\n this.validateEvt(evt)\n let found = 0;\n // first check the normal store\n let nStore = this.normalStore;\n this.logger('$trigger', nStore)\n if (nStore.has(evt)) {\n this.logger('$trigger', evt, 'found')\n let nSet = Array.from(nStore.get(evt))\n let ctn = nSet.length;\n let hasOnce = false;\n let hasOnly = false;\n for (let i=0; i < ctn; ++i) {\n ++found;\n // this.logger('found', found)\n let [ _, callback, ctx, type ] = nSet[i]\n this.run(callback, payload, context || ctx)\n if (type === 'once' || type === 'onlyOnce') {\n hasOnce = true;\n }\n }\n if (hasOnce) {\n nStore.delete(evt)\n }\n return found;\n }\n // now this is not register yet\n this.addToLazyStore(evt, payload, context, type)\n return found;\n }\n\n /**\n * this is an alias to the $trigger\n * @NOTE breaking change in V1.6.0 we swap the parameter around\n * @param {string} evt event name\n * @param {*} params pass to the callback\n * @param {string} type of call\n * @param {object} context what context callback execute in\n * @return {*} from $trigger\n */\n $call(evt, params, type = false, context = null) {\n let args = [evt, params]\n args.push(context, type)\n return Reflect.apply(this.$trigger, this, args)\n }\n\n /**\n * remove the evt from all the stores\n * @param {string} evt name\n * @return {boolean} true actually delete something\n */\n $off(evt) {\n this.validateEvt(evt)\n let stores = [ this.lazyStore, this.normalStore ]\n let found = false;\n stores.forEach(store => {\n if (store.has(evt)) {\n found = true;\n store.delete(evt)\n }\n })\n return found;\n }\n\n /**\n * return all the listener from the event\n * @param {string} evtName event name\n * @param {boolean} [full=false] if true then return the entire content\n * @return {array|boolean} listerner(s) or false when not found\n */\n $get(evt, full = false) {\n this.validateEvt(evt)\n let store = this.normalStore;\n if (store.has(evt)) {\n return Array\n .from(store.get(evt))\n .map( l => {\n if (full) {\n return l;\n }\n let [key, callback, ] = l;\n return callback;\n })\n }\n return false;\n }\n\n /**\n * store the return result from the run\n * @param {*} value whatever return from callback\n */\n set $done(value) {\n this.logger('set $done', value)\n if (this.keep) {\n this.result.push(value)\n } else {\n this.result = value;\n }\n }\n\n /**\n * @TODO is there any real use with the keep prop?\n * getter for $done\n * @return {*} whatever last store result\n */\n get $done() {\n if (this.keep) {\n this.logger(this.result)\n return this.result[this.result.length - 1]\n }\n return this.result;\n }\n\n /////////////////////////////\n // PRIVATE METHODS //\n /////////////////////////////\n\n /**\n * validate the event name\n * @param {string} evt event name\n * @return {boolean} true when OK\n */\n validateEvt(evt) {\n if (typeof evt === 'string') {\n return true;\n }\n throw new Error(`event name must be string type!`)\n }\n\n /**\n * Simple quick check on the two main parameters\n * @param {string} evt event name\n * @param {function} callback function to call\n * @return {boolean} true when OK\n */\n validate(evt, callback) {\n if (this.validateEvt(evt)) {\n if (typeof callback === 'function') {\n return true;\n }\n }\n throw new Error(`callback required to be function type!`)\n }\n\n /**\n * Check if this type is correct or not added in V1.5.0\n * @param {string} type for checking\n * @return {boolean} true on OK\n */\n validateType(type) {\n const types = ['on', 'only', 'once', 'onlyOnce']\n return !!types.filter(t => type === t).length;\n }\n\n /**\n * Run the callback\n * @param {function} callback function to execute\n * @param {array} payload for callback\n * @param {object} ctx context or null\n * @return {void} the result store in $done\n */\n run(callback, payload, ctx) {\n this.logger('run', callback, payload, ctx)\n this.$done = Reflect.apply(callback, ctx, this.toArray(payload))\n }\n\n /**\n * Take the content out and remove it from store id by the name\n * @param {string} evt event name\n * @param {string} [storeName = lazyStore] name of store\n * @return {object|boolean} content or false on not found\n */\n takeFromStore(evt, storeName = 'lazyStore') {\n let store = this[storeName]; // it could be empty at this point\n if (store) {\n this.logger('takeFromStore', storeName, store)\n if (store.has(evt)) {\n let content = store.get(evt)\n this.logger('takeFromStore', content)\n store.delete(evt)\n return content;\n }\n return false;\n }\n throw new Error(`${storeName} is not supported!`)\n }\n\n /**\n * The add to store step is similar so make it generic for resuse\n * @param {object} store which store to use\n * @param {string} evt event name\n * @param {spread} args because the lazy store and normal store store different things\n * @return {array} store and the size of the store\n */\n addToStore(store, evt, ...args) {\n let fnSet;\n if (store.has(evt)) {\n this.logger('addToStore', `${evt} existed`)\n fnSet = store.get(evt)\n } else {\n this.logger('addToStore', `create new Set for ${evt}`)\n // this is new\n fnSet = new Set()\n }\n // lazy only store 2 items - this is not the case in V1.6.0 anymore\n // we need to check the first parameter is string or not\n if (args.length > 2) {\n if (Array.isArray(args[0])) { // lazy store\n // check if this type of this event already register in the lazy store\n let [,,t] = args;\n if (!this.checkTypeInLazyStore(evt, t)) {\n fnSet.add(args)\n }\n } else {\n if (!this.checkContentExist(args, fnSet)) {\n this.logger('addToStore', `insert new`, args)\n fnSet.add(args)\n }\n }\n } else { // add straight to lazy store\n fnSet.add(args)\n }\n store.set(evt, fnSet)\n return [store, fnSet.size]\n }\n\n /**\n * @param {array} args for compare\n * @param {object} fnSet A Set to search from\n * @return {boolean} true on exist\n */\n checkContentExist(args, fnSet) {\n let list = Array.from(fnSet)\n return !!list.filter(l => {\n let [hash,] = l;\n if (hash === args[0]) {\n return true;\n }\n return false;\n }).length;\n }\n\n /**\n * get the existing type to make sure no mix type add to the same store\n * @param {string} evtName event name\n * @param {string} type the type to check\n * @return {boolean} true you can add, false then you can't add this type\n */\n checkTypeInStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let all = this.$get(evtName, true)\n if (all === false) {\n // pristine it means you can add\n return true;\n }\n // it should only have ONE type in ONE event store\n return !all.filter(list => {\n let [ ,,,t ] = list;\n return type !== t;\n }).length;\n }\n\n /**\n * This is checking just the lazy store because the structure is different\n * therefore we need to use a new method to check it\n */\n checkTypeInLazyStore(evtName, type) {\n this.validateEvt(evtName)\n this.validateEvt(type)\n let store = this.lazyStore.get(evtName)\n this.logger('checkTypeInLazyStore', store)\n if (store) {\n return !!Array\n .from(store)\n .filter(l => {\n let [,,t] = l;\n return t !== type;\n }).length\n }\n return false;\n }\n\n /**\n * wrapper to re-use the addToStore,\n * V1.3.0 add extra check to see if this type can add to this evt\n * @param {string} evt event name\n * @param {string} type on or once\n * @param {function} callback function\n * @param {object} context the context the function execute in or null\n * @return {number} size of the store\n */\n addToNormalStore(evt, type, callback, context = null) {\n this.logger('addToNormalStore', evt, type, 'add to normal store')\n // @TODO we need to check the existing store for the type first!\n if (this.checkTypeInStore(evt, type)) {\n this.logger(`${type} can add to ${evt} store`)\n let key = this.hashFnToKey(callback)\n let args = [this.normalStore, evt, key, callback, context, type]\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.normalStore = _store;\n return size;\n }\n return false;\n }\n\n /**\n * Add to lazy store this get calls when the callback is not register yet\n * so we only get a payload object or even nothing\n * @param {string} evt event name\n * @param {array} payload of arguments or empty if there is none\n * @param {object} [context=null] the context the callback execute in\n * @param {string} [type=false] register a type so no other type can add to this evt\n * @return {number} size of the store\n */\n addToLazyStore(evt, payload = [], context = null, type = false) {\n // this is add in V1.6.0\n // when there is type then we will need to check if this already added in lazy store\n // and no other type can add to this lazy store\n let args = [this.lazyStore, evt, this.toArray(payload), context]\n if (type) {\n args.push(type)\n }\n let [_store, size] = Reflect.apply(this.addToStore, this, args)\n this.lazyStore = _store;\n return size;\n }\n\n /**\n * make sure we store the argument correctly\n * @param {*} arg could be array\n * @return {array} make sured\n */\n toArray(arg) {\n return Array.isArray(arg) ? arg : [arg];\n }\n\n /**\n * setter to store the Set in private\n * @param {object} obj a Set\n */\n set normalStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_STORE.set(this, obj)\n }\n\n /**\n * @return {object} Set object\n */\n get normalStore() {\n return NB_EVENT_SERVICE_PRIVATE_STORE.get(this)\n }\n\n /**\n * setter to store the Set in lazy store\n * @param {object} obj a Set\n */\n set lazyStore(obj) {\n NB_EVENT_SERVICE_PRIVATE_LAZY.set(this , obj)\n }\n\n /**\n * @return {object} the lazy store Set\n */\n get lazyStore() {\n return NB_EVENT_SERVICE_PRIVATE_LAZY.get(this)\n }\n\n /**\n * generate a hashKey to identify the function call\n * The build-in store some how could store the same values!\n * @param {function} fn the converted to string function\n * @return {string} hashKey\n */\n hashFnToKey(fn) {\n return genHaskKey(fn.toString()) + '';\n }\n\n}\n","// default\nimport NBEventService from './src/event-service'\n\nexport default NBEventService\n","// this will generate a event emitter and will be use everywhere\nimport NBEventService from 'nb-event-service'\n\nconst ee = new NBEventService()\n// output\nexport default ee\n","// Generate the resolver for developer to use\n\n// @TODO when enableAuth we need to add one extra check\n// before the resolver call make it to the core\n// which is checking the login state, if the developer\n// is calling a private method without logging in\n// then we should throw the JsonqlForbiddenError at this point\n// instead of making a round trip to the server\n\nimport { validateAsync } from 'jsonql-params-validator'\nimport {\n JsonqlValidationError,\n JsonqlError,\n clientErrorsHandler,\n finalCatch\n} from 'jsonql-errors'\nimport ee from './ee'\nimport { LOGOUT_NAME, ISSUER_NAME, KEY_WORD } from 'jsonql-constants'\n\n/**\n * generate authorisation specific methods\n * @param {object} jsonqlInstance instance of this\n * @param {string} name of method\n * @param {object} opts configuration\n * @param {object} contract to match\n * @return {function} for use\n */\nconst authMethodGenerator = (jsonqlInstance, name, opts, contract) => {\n return (...args) => {\n const params = contract.auth[name].params;\n const values = params.map((p, i) => args[i])\n const header = args[params.length] || {};\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [name, values, header])\n )\n .catch(finalCatch)\n }\n}\n\n/**\n * @param {object} jsonqlInstance jsonql class instance\n * @param {object} config options\n * @param {object} contract the contract\n * @return {object} constructed functions call\n */\nconst generator = (jsonqlInstance, config, contract) => {\n\n let obj = {query: {}, mutation: {}, auth: {}}\n // process the query first\n for (let queryFn in contract.query) {\n // to keep it clean we use a param to id the auth method\n // const fn = (_contract.query[queryFn].auth === true) ? 'auth' : queryFn;\n // generate the query method\n obj.query[queryFn] = (...args) => {\n const params = contract.query[queryFn].params;\n const _args = params.map((param, i) => args[i])\n // debug('query', queryFn, _params);\n // @TODO this need to change\n // the +1 parameter is the extra headers we want to pass\n const header = args[params.length] || {};\n // @TODO validate against the type\n return validateAsync(_args, params)\n .then(() => jsonqlInstance\n .query\n .apply(jsonqlInstance, [queryFn, _args, header])\n )\n .catch(finalCatch)\n }\n }\n // process the mutation, the reason the mutation has a fixed number of parameters\n // there is only the payload, and conditions parameters\n // plus a header at the end\n for (let mutationFn in contract.mutation) {\n obj.mutation[mutationFn] = (payload, conditions, header = {}) => {\n const args = [payload, conditions];\n const params = contract.mutation[mutationFn].params;\n return validateAsync(args, params)\n .then(() => jsonqlInstance\n .mutation\n .apply(jsonqlInstance, [mutationFn, payload, conditions, header])\n )\n .catch(finalCatch)\n }\n }\n // there is only one call issuer we want here\n if (config.enableAuth && contract.auth) {\n const { loginHandlerName, logoutHandlerName } = config;\n if (contract.auth[loginHandlerName]) {\n // changing to the name the config specify\n obj[loginHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, loginHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLoginAction)\n .then(token => {\n ee.$trigger(ISSUER_NAME, token)\n return token;\n })\n }\n }\n if (contract.auth[logoutHandlerName]) {\n obj[logoutHandlerName] = (...args) => {\n const fn = authMethodGenerator(jsonqlInstance, logoutHandlerName, config, contract)\n return fn.apply(null, args)\n .then(jsonqlInstance.postLogoutAction)\n .then(r => {\n ee.$trigger(LOGOUT_NAME, r)\n return r;\n })\n }\n } else {\n obj[logoutHandlerName] = () => {\n jsonqlInstance.postLogoutAction(KEY_WORD)\n ee.$trigger(LOGOUT_NAME, KEY_WORD)\n }\n }\n /**\n * new method to allow retrieve the current login user data\n * @return {*} userdata\n */\n obj.userdata = () => jsonqlInstance.userdata;\n }\n // store this once again and export it\n if (obj.returnInstance) {\n obj.jsonqlClientInstance = jsonqlInstance;\n }\n // allow getting the token for valdiate agains the socket\n obj.getToken = () => jsonqlInstance.rawAuthToken;\n // this will pass to the ws-client if needed\n obj.eventEmitter = ee;\n // output\n return obj;\n};\n\nexport default generator;\n","// we must ensure the user passing the correct options\n// therefore we need to validate against the properties as well\n\nimport { appProps, constProps } from './base-options'\nimport { checkConfigAsync } from 'jsonql-params-validator'\n\nexport default config => {\n let { contract } = config;\n return checkConfigAsync(config, appProps, constProps)\n .then(opts => {\n opts.contract = contract;\n return opts;\n })\n}\n","// export interface\nimport checkOptions from './check-options'\n\nexport default checkOptions\n","// this is new for the flyio and normalize the name from now on\nimport JsonqlBaseClient from './lib/base'\nimport generator from './lib/jsonql-api-generator'\nimport checkOptions from './lib/options'\nimport { getContractFromConfig } from './lib/utils'\n\n/**\n * Main interface for jsonql fetch api\n * @param {object} config\n * @return {object} jsonql client\n */\nexport default function(config = {}) {\n return checkOptions(config)\n .then(opts => (\n {\n baseClient: new JsonqlBaseClient(opts),\n opts: opts\n }\n ))\n .then( ({baseClient, opts}) => (\n getContractFromConfig(baseClient, opts.contract)\n .then(contract => generator(baseClient, opts, contract)\n )\n )\n );\n}\n","// main export interface\n\n// @2019-05-09 new interface export with Fetch\nimport jsonqlApi from './jsonql-api'\nexport default jsonqlApi\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;CCAA;;;;;;ACAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;CCAA;;;;;;;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;CCAA;;;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;;;;CCAA;;CCAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCAA;;;;;;;;"} \ No newline at end of file diff --git a/packages/http-client/package.json b/packages/http-client/package.json index f12b6983096aadad28422fb8a94c2ef890b62a63..418070d2b3850610338b7fd8abd1eb2862eb0837 100755 --- a/packages/http-client/package.json +++ b/packages/http-client/package.json @@ -61,7 +61,7 @@ "debug": "^4.1.1", "esm": "^3.2.25", "glob": "^7.1.4", - "jsonql-koa": "^1.3.0", + "jsonql-koa": "^1.3.1", "koa-favicon": "^2.0.1", "nyc": "^14.1.1", "promise-polyfill": "8.1.3", diff --git a/packages/http-client/src/lib/base/base-cls.js b/packages/http-client/src/lib/base/base-cls.js index fcc66cbccc50b59a26314c12227a277eb8caa8b6..15bee396309d3bf29738e0b52ab5d61a482f0592 100644 --- a/packages/http-client/src/lib/base/base-cls.js +++ b/packages/http-client/src/lib/base/base-cls.js @@ -6,6 +6,8 @@ import { isObject, isArray, inArray } from 'jsonql-params-validator' import { JsonqlValidationError } from 'jsonql-errors' // chaining into the classes import AuthCls from './auth-cls' + + // This class will only focus on the storage system export default class JsonqlBaseClient extends AuthCls { @@ -15,6 +17,7 @@ export default class JsonqlBaseClient extends AuthCls { // @TODO set storeIt(args) { + console.info('storeIt', args) // the args MUST contain [0] the key , [1] the content [2] optional expired in if (isArray(args) && args.length >= 2) { Reflect.apply(localStore.set, localStore, args) @@ -40,16 +43,19 @@ export default class JsonqlBaseClient extends AuthCls { // by the time it call the save contract already been checked set jsonqlContract(args) { - const key = this.opts.storageKey + const key = this.opts.storageKey; + let _args = [ key ] let [ contract, expired ] = args; // get the endpoint index let contracts = localStore.get(key) || [] - constracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; - let _args = [key].push(contracts) + contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] = contract; + _args.push(contracts) if (expired) { _args.push(expired) } - this.storeIt = _args; + if (this.opts.keepContract) { + this.storeIt = _args; + } } /** @@ -93,6 +99,8 @@ export default class JsonqlBaseClient extends AuthCls { /** * This also manage the index internally + * There is NO need to store them in an array + * because each instance contain one end point * @return {string} the end point to call */ get jsonqlEndpoint() { @@ -113,12 +121,9 @@ export default class JsonqlBaseClient extends AuthCls { * @return {object|boolean} as described above */ get jsonqlContract() { - if (this.opts.keepContract) { - const key = this.opts.storageKey - let contracts = localStore.get(key) || [] - return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; - } - return false; + const key = this.opts.storageKey + let contracts = localStore.get(key) || [] + return contracts[ this[ENDPOINT_TABLE + 'Index'] ] || false; } /** @@ -136,7 +141,7 @@ export default class JsonqlBaseClient extends AuthCls { // this one store in the session store /** * get login userdata decoded jwt - * @return {object|null} + * @return {object|null} */ get jsonqlUserdata() { return sessionStore.get(USERDATA_TABLE) diff --git a/packages/http-client/src/lib/base/contract-cls.js b/packages/http-client/src/lib/base/contract-cls.js index 81757261b98274766d7a98e43d825dcefa6c2c42..24a00fb0c86309434bb58ed50a79747dc7f20204 100644 --- a/packages/http-client/src/lib/base/contract-cls.js +++ b/packages/http-client/src/lib/base/contract-cls.js @@ -1,8 +1,9 @@ // all the contract related methods will be here import { localStore } from '../stores'; -import { timestamp, isJsonqlContract } from '../utils'; +import { ENDPOINT_TABLE, timestamp, isJsonqlContract } from '../utils'; import HttpClass from './http-cls'; - +import { JsonqlValidationError } from 'jsonql-errors' +// export export default class ContractClass extends HttpClass { constructor(opts) { @@ -27,9 +28,13 @@ export default class ContractClass extends HttpClass { * @return {object} contract */ getContract() { - const contract = this.readContract() - if (contract) { - return Promise.resolve(contract) + const contracts = this.readContract() + console.info('getContract first call', contracts) + if (contracts && Array.isArray(contracts)) { + const contract = contracts[ this[ENDPOINT_TABLE + 'Index'] || 0 ] + if (contract) { + return Promise.resolve(contract) + } } return this.get() .then( this.storeContract.bind(this) ) @@ -56,16 +61,20 @@ export default class ContractClass extends HttpClass { storeContract(contract) { // first need to check if the contract is a contract if (!isJsonqlContract(contract)) { - return false; + throw new JsonqlValidationError(`Contract is malformed!`) + //return false; } let args = [contract] if (this.opts.contractExpired) { - let expired = parseFloat(this.opts.contractExpired); + let expired = parseFloat(this.opts.contractExpired) if (!isNaN(expired) && expired > 0) { - args.push(expired); + args.push(expired) } } - this.jsonqlContract = contract; + // calling the setter + this.jsonqlContract = args; + // return it + console.info('storeContract return result', contract) return contract; } diff --git a/packages/http-client/src/lib/base/http-cls.js b/packages/http-client/src/lib/base/http-cls.js index cee7bbdd1dedd5b6224346bca64930f417b29d96..a36343209574395058be5d07079171ed03554256 100644 --- a/packages/http-client/src/lib/base/http-cls.js +++ b/packages/http-client/src/lib/base/http-cls.js @@ -60,7 +60,7 @@ export default class HttpClass { return this.fly.request( this.jsonqlEndpoint, payload, - merge({}, {method: POST, params }, options) + merge({}, { method: POST, params }, options) ) } @@ -141,7 +141,14 @@ export default class HttpClass { return this.request({}, {method: 'GET'}, this.contractHeader) .then(clientErrorsHandler) .then(result => { - console.info('get contract result', result) + console.info('144 get contract result', result) + // when refresh the window the result is different! + // @TODO need to check the Koa side about why is that + // also it should set a flag if we want the description or not + if (result.cache && result.contract) { + return result.contract; + } + // just the normal result return result }) } diff --git a/packages/http-client/src/lib/jsonql-api-generator.js b/packages/http-client/src/lib/jsonql-api-generator.js index 2652acf1853817fc5ffba5c87c9899441747c28d..2cf47664f31c181216c14a9c5a91611a8063a255 100755 --- a/packages/http-client/src/lib/jsonql-api-generator.js +++ b/packages/http-client/src/lib/jsonql-api-generator.js @@ -94,7 +94,7 @@ const generator = (jsonqlInstance, config, contract) => { return fn.apply(null, args) .then(jsonqlInstance.postLoginAction) .then(token => { - ee.emitEvent(ISSUER_NAME, token) + ee.$trigger(ISSUER_NAME, token) return token; }) } @@ -105,14 +105,14 @@ const generator = (jsonqlInstance, config, contract) => { return fn.apply(null, args) .then(jsonqlInstance.postLogoutAction) .then(r => { - ee.emitEvent(LOGOUT_NAME, r) + ee.$trigger(LOGOUT_NAME, r) return r; }) } } else { obj[logoutHandlerName] = () => { jsonqlInstance.postLogoutAction(KEY_WORD) - ee.emitEvent(LOGOUT_NAME, KEY_WORD) + ee.$trigger(LOGOUT_NAME, KEY_WORD) } } /** diff --git a/packages/http-client/tests/qunit/files/base-test.js b/packages/http-client/tests/qunit/files/base-test.js index 9895c358894d004af53154521c13f84c0c39955b..1356289120f26e0f027b6ee147fd94659a24093c 100644 --- a/packages/http-client/tests/qunit/files/base-test.js +++ b/packages/http-client/tests/qunit/files/base-test.js @@ -2,9 +2,13 @@ QUnit.test('It should able to use the client to contact the server with static contract', function(assert) { var done1 = assert.async() - var jclient = jsonqlClient({hostname: 'http://localhost:8081'}) + var done2 = assert.async() - jclient.then(function(client) { + jsonqlClient({ + hostname: 'http://localhost:8081', + keepContract: false + }) + .then(function(client) { console.info(client) @@ -12,15 +16,12 @@ QUnit.test('It should able to use the client to contact the server with static c assert.equal('Hello world!', result, "Hello world test done") done1() }) - }) - var done2 = assert.async() - - jclient.then(function(client) { client.query.getSomething(1).catch(err => { assert.equal(err.className, 'JsonqlValidationError', 'Expect validation error') done2() }) + }) }) diff --git a/packages/http-client/tests/qunit/files/stores-test.js b/packages/http-client/tests/qunit/files/stores-test.js index d2b21b418cf40cc79ecef3c8fce074e6a83b0541..09d5e46f84ade617a3606e9f82ed2dbf8536ff6c 100644 --- a/packages/http-client/tests/qunit/files/stores-test.js +++ b/packages/http-client/tests/qunit/files/stores-test.js @@ -13,30 +13,35 @@ QUnit.module( "store", { */ QUnit.test('It should able to use the client to contact the server with static contract', function(assert) { localStore = JsonqlStores.localStore; - //// assert.expect(2) + // assert.expect(2) localStore.set('someKey[0]', 'test data') assert.ok('test data', localStore.get('someKey[0]')) + localStore.remove('someKey[0]') + + + /* + + // this test should make it standalone + var done1 = assert.async() var toset = 'just some value' + localStore.set('being-watch', toset) + + setTimeout(function() { + localStore.remove('being-watch') + }, 500) + localStore.watch('being-watch', function(value) { console.info('value', value) let val = localStore.get('being-watch') assert.ok(val, toset) - - - done1() }) + */ - localStore.set('being-watch', toset) - - setTimeout(function() { - localStore.remove('someKey[0]') - localStore.remove('being-watch') - }, 1000) })