stream-chat 8.45.1 → 8.45.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"browser.full-bundle.min.js","sources":["../node_modules/base64-js/index.js","../src/base64.ts","../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","../node_modules/@babel/runtime/helpers/esm/createClass.js","../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../node_modules/regenerator-runtime/runtime.js","../node_modules/@babel/runtime/regenerator/index.js","../src/campaign.ts","../node_modules/@babel/runtime/helpers/esm/extends.js","../node_modules/@babel/runtime/helpers/esm/typeof.js","../node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js","../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","../node_modules/axios/lib/helpers/bind.js","../node_modules/axios/lib/utils.js","../node_modules/axios/lib/core/AxiosError.js","../node_modules/axios/lib/helpers/toFormData.js","../node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../node_modules/axios/lib/helpers/buildURL.js","../node_modules/axios/lib/core/InterceptorManager.js","../node_modules/axios/lib/defaults/transitional.js","../node_modules/axios/lib/platform/browser/index.js","../node_modules/axios/lib/platform/browser/classes/URLSearchParams.js","../node_modules/axios/lib/platform/browser/classes/FormData.js","../node_modules/axios/lib/platform/browser/classes/Blob.js","../node_modules/axios/lib/helpers/formDataToJSON.js","../node_modules/axios/lib/defaults/index.js","../node_modules/axios/lib/helpers/toURLEncodedForm.js","../node_modules/axios/lib/helpers/parseHeaders.js","../node_modules/axios/lib/core/AxiosHeaders.js","../node_modules/axios/lib/core/transformData.js","../node_modules/axios/lib/cancel/isCancel.js","../node_modules/axios/lib/cancel/CanceledError.js","../node_modules/axios/lib/helpers/cookies.js","../node_modules/axios/lib/core/buildFullPath.js","../node_modules/axios/lib/helpers/isAbsoluteURL.js","../node_modules/axios/lib/helpers/combineURLs.js","../node_modules/axios/lib/helpers/isURLSameOrigin.js","../node_modules/axios/lib/adapters/xhr.js","../node_modules/axios/lib/helpers/speedometer.js","../node_modules/axios/lib/adapters/adapters.js","../node_modules/axios/lib/helpers/null.js","../node_modules/axios/lib/core/settle.js","../node_modules/axios/lib/helpers/parseProtocol.js","../node_modules/axios/lib/core/dispatchRequest.js","../node_modules/axios/lib/core/mergeConfig.js","../node_modules/axios/lib/env/data.js","../node_modules/axios/lib/helpers/validator.js","../node_modules/axios/lib/core/Axios.js","../node_modules/axios/lib/cancel/CancelToken.js","../node_modules/axios/lib/helpers/HttpStatusCode.js","../node_modules/axios/lib/axios.js","../node_modules/axios/lib/helpers/spread.js","../node_modules/axios/lib/helpers/isAxiosError.js","../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","../node_modules/form-data/lib/browser.js","../src/utils.ts","../src/constants.ts","../src/channel_state.ts","../src/channel.ts","../src/client_state.ts","../node_modules/isomorphic-ws/browser.js","../src/insights.ts","../src/connection.ts","../src/signing.ts","../jsonwebtoken","../crypto","../src/connection_fallback.ts","../src/token_manager.ts","../src/errors.ts","../src/segment.ts","../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","../node_modules/@babel/runtime/helpers/esm/construct.js","../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","../src/types.ts","../node_modules/@babel/runtime/helpers/esm/inherits.js","../src/store.ts","../src/thread.ts","../src/moderation.ts","../src/thread_manager.ts","../src/poll.ts","../src/poll_manager.ts","../src/client.ts","../https","../src/permissions.ts","../src/events.ts"],"sourcesContent":["'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n","import { fromByteArray } from 'base64-js';\n\nfunction isString<T>(arrayOrString: string | T[]): arrayOrString is string {\n return typeof (arrayOrString as string) === 'string';\n}\n\ntype MapGenericCallback<T, U> = (value: T, index: number, array: T[]) => U;\ntype MapStringCallback<U> = (value: string, index: number, string: string) => U;\n\nfunction isMapStringCallback<T, U>(\n arrayOrString: string | T[],\n callback: MapGenericCallback<T, U> | MapStringCallback<U>,\n): callback is MapStringCallback<U> {\n return !!callback && isString(arrayOrString);\n}\n\n// source - https://github.com/beatgammit/base64-js/blob/master/test/convert.js#L72\nfunction map<T, U>(array: T[], callback: MapGenericCallback<T, U>): U[];\nfunction map<U>(string: string, callback: MapStringCallback<U>): U[];\nfunction map<T, U>(arrayOrString: string | T[], callback: MapGenericCallback<T, U> | MapStringCallback<U>): U[] {\n const res = [];\n\n if (isString(arrayOrString) && isMapStringCallback(arrayOrString, callback)) {\n for (let k = 0, len = arrayOrString.length; k < len; k++) {\n if (arrayOrString.charAt(k)) {\n const kValue = arrayOrString.charAt(k);\n const mappedValue = callback(kValue, k, arrayOrString);\n res[k] = mappedValue;\n }\n }\n } else if (!isString(arrayOrString) && !isMapStringCallback(arrayOrString, callback)) {\n for (let k = 0, len = arrayOrString.length; k < len; k++) {\n if (k in arrayOrString) {\n const kValue = arrayOrString[k];\n const mappedValue = callback(kValue, k, arrayOrString);\n res[k] = mappedValue;\n }\n }\n }\n\n return res;\n}\n\nexport const encodeBase64 = (data: string): string =>\n fromByteArray(new Uint8Array(map(data, (char) => char.charCodeAt(0))));\n\n// base-64 decoder throws exception if encoded string is not padded by '=' to make string length\n// in multiples of 4. So gonna use our own method for this purpose to keep backwards compatibility\n// https://github.com/beatgammit/base64-js/blob/master/index.js#L26\nexport const decodeBase64 = (s: string): string => {\n const e = {} as { [key: string]: number },\n w = String.fromCharCode,\n L = s.length;\n let i,\n b = 0,\n c,\n x,\n l = 0,\n a,\n r = '';\n const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n for (i = 0; i < 64; i++) {\n e[A.charAt(i)] = i;\n }\n for (x = 0; x < L; x++) {\n c = e[s.charAt(x)];\n b = (b << 6) + c;\n l += 6;\n while (l >= 8) {\n ((a = (b >>> (l -= 8)) & 0xff) || x < L - 2) && (r += w(a));\n }\n }\n return r;\n};\n","function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n \"GeneratorFunction\"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, \"GeneratorFunction\");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n}\n","module.exports = require(\"regenerator-runtime\");\n","import { StreamChat } from './client';\nimport { CampaignData, DefaultGenerics, ExtendableGenerics } from './types';\n\nexport class Campaign<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n id: string | null;\n data?: CampaignData;\n client: StreamChat<StreamChatGenerics>;\n\n constructor(client: StreamChat<StreamChatGenerics>, id: string | null, data?: CampaignData) {\n this.client = client;\n this.id = id;\n this.data = data;\n }\n\n async create() {\n const body = {\n id: this.id,\n message_template: this.data?.message_template,\n segment_ids: this.data?.segment_ids,\n sender_id: this.data?.sender_id,\n channel_template: this.data?.channel_template,\n create_channels: this.data?.create_channels,\n description: this.data?.description,\n name: this.data?.name,\n user_ids: this.data?.user_ids,\n };\n\n const result = await this.client.createCampaign(body);\n\n this.id = result.campaign.id;\n this.data = result.campaign;\n return result;\n }\n\n verifyCampaignId() {\n if (!this.id) {\n throw new Error(\n 'Campaign id is missing. Either create the campaign using campaign.create() or set the id during instantiation - const campaign = client.campaign(id)',\n );\n }\n }\n\n async start(options?: { scheduledFor?: string; stopAt?: string }) {\n this.verifyCampaignId();\n\n return await this.client.startCampaign(this.id as string, options);\n }\n\n async update(data: Partial<CampaignData>) {\n this.verifyCampaignId();\n\n return this.client.updateCampaign(this.id as string, data);\n }\n\n async delete() {\n this.verifyCampaignId();\n\n return await this.client.deleteCampaign(this.id as string);\n }\n\n async stop() {\n this.verifyCampaignId();\n\n return this.client.stopCampaign(this.id as string);\n }\n\n async get() {\n this.verifyCampaignId();\n\n return this.client.getCampaign(this.id as string);\n }\n}\n","export default function _extends() {\n _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n}","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function _typeof(obj) {\n return typeof obj;\n };\n } else {\n _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}","import objectWithoutPropertiesLoose from \"./objectWithoutPropertiesLoose.js\";\nexport default function _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}","export default function _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val);\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object<any, any>} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[Symbol.iterator];\n\n const iterator = generator.call(obj);\n\n let result;\n\n while ((result = iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array<boolean>}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n value = +value;\n return Number.isFinite(value) ? value : defaultValue;\n}\n\nconst ALPHA = 'abcdefghijklmnopqrstuvwxyz'\n\nconst DIGIT = '0123456789';\n\nconst ALPHABET = {\n DIGIT,\n ALPHA,\n ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT\n}\n\nconst generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {\n let str = '';\n const {length} = alphabet;\n while (size--) {\n str += alphabet[Math.random() * length|0]\n }\n\n return str;\n}\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n ALPHABET,\n generateString,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n response && (this.response = response);\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.response && this.response.status ? this.response.status : null\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n AxiosError.call(axiosError, error.message, code, config, request, response);\n\n axiosError.cause = error;\n\n axiosError.name = error.name;\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array<any>} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object<any, any>} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object<string, any>} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array<String|Number>} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object<string, any>} params - The parameters to be converted to a FormData object.\n * @param {Object<string, any>} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?object} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst isStandardBrowserEnv = (() => {\n let product;\n if (typeof navigator !== 'undefined' && (\n (product = navigator.product) === 'ReactNative' ||\n product === 'NativeScript' ||\n product === 'NS')\n ) {\n return false;\n }\n\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n})();\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\n const isStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n isStandardBrowserEnv,\n isStandardBrowserWebWorkerEnv,\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array<any>} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object<string, any> | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n if (!hasJSONContentType) {\n return data;\n }\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n }\n }, options));\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.isStandardBrowserEnv ?\n\n// Standard browser envs support document.cookie\n (function standardBrowserEnv() {\n return {\n write: function write(name, value, expires, path, domain, secure) {\n const cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n };\n })() :\n\n// Non standard browser env (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return {\n write: function write() {},\n read: function read() { return null; },\n remove: function remove() {}\n };\n })();\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL) {\n if (baseURL && !isAbsoluteURL(requestedURL)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"<scheme>://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.isStandardBrowserEnv ?\n\n// Standard browser envs have full support of the APIs needed to test\n// whether the request URL is of the same origin as current location.\n (function standardBrowserEnv() {\n const msie = /(msie|trident)/i.test(navigator.userAgent);\n const urlParsingNode = document.createElement('a');\n let originURL;\n\n /**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\n function resolveURL(url) {\n let href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n }\n\n originURL = resolveURL(window.location.href);\n\n /**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestURL The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\n return function isURLSameOrigin(requestURL) {\n const parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n return (parsed.protocol === originURL.protocol &&\n parsed.host === originURL.host);\n };\n })() :\n\n // Non standard browser envs (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return function isURLSameOrigin() {\n return true;\n };\n })();\n","'use strict';\n\nimport utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport cookies from './../helpers/cookies.js';\nimport buildURL from './../helpers/buildURL.js';\nimport buildFullPath from '../core/buildFullPath.js';\nimport isURLSameOrigin from './../helpers/isURLSameOrigin.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport speedometer from '../helpers/speedometer.js';\n\nfunction progressEventReducer(listener, isDownloadStream) {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e\n };\n\n data[isDownloadStream ? 'download' : 'upload'] = true;\n\n listener(data);\n };\n}\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n let requestData = config.data;\n const requestHeaders = AxiosHeaders.from(config.headers).normalize();\n const responseType = config.responseType;\n let onCanceled;\n function done() {\n if (config.cancelToken) {\n config.cancelToken.unsubscribe(onCanceled);\n }\n\n if (config.signal) {\n config.signal.removeEventListener('abort', onCanceled);\n }\n }\n\n let contentType;\n\n if (utils.isFormData(requestData)) {\n if (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv) {\n requestHeaders.setContentType(false); // Let the browser set it\n } else if(!requestHeaders.getContentType(/^\\s*multipart\\/form-data/)){\n requestHeaders.setContentType('multipart/form-data'); // mobile/desktop app frameworks\n } else if(utils.isString(contentType = requestHeaders.getContentType())){\n // fix semicolon duplication issue for ReactNative FormData implementation\n requestHeaders.setContentType(contentType.replace(/^\\s*(multipart\\/form-data);+/, '$1'))\n }\n }\n\n let request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n const username = config.auth.username || '';\n const password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n requestHeaders.set('Authorization', 'Basic ' + btoa(username + ':' + password));\n }\n\n const fullPath = buildFullPath(config.baseURL, config.url);\n\n request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = config.transitional || transitionalDefaults;\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (platform.isStandardBrowserEnv) {\n // Add xsrf header\n // regarding CVE-2023-45857 config.withCredentials condition was removed temporarily\n const xsrfValue = isURLSameOrigin(fullPath) && config.xsrfCookieName && cookies.read(config.xsrfCookieName);\n\n if (xsrfValue) {\n requestHeaders.set(config.xsrfHeaderName, xsrfValue);\n }\n }\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(config.withCredentials)) {\n request.withCredentials = !!config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = config.responseType;\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', progressEventReducer(config.onDownloadProgress, true));\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', progressEventReducer(config.onUploadProgress));\n }\n\n if (config.cancelToken || config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n config.cancelToken && config.cancelToken.subscribe(onCanceled);\n if (config.signal) {\n config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(fullPath);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? thing.toJSON() : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)\n };\n\n utils.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","export const VERSION = \"1.6.0\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift.apply(chain, requestInterceptorChain);\n chain.push.apply(chain, responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n i = 0;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","/* eslint-env browser */\nmodule.exports = typeof self == 'object' ? self.FormData : window.FormData;\n","import FormData from 'form-data';\nimport {\n AscDesc,\n ExtendableGenerics,\n DefaultGenerics,\n Logger,\n OwnUserBase,\n OwnUserResponse,\n UserResponse,\n MessageResponse,\n FormatMessageResponse,\n ReactionGroupResponse,\n MessageSet,\n MessagePaginationOptions,\n} from './types';\nimport { AxiosRequestConfig } from 'axios';\n\n/**\n * logChatPromiseExecution - utility function for logging the execution of a promise..\n * use this when you want to run the promise and handle errors by logging a warning\n *\n * @param {Promise<T>} promise The promise you want to run and log\n * @param {string} name A descriptive name of what the promise does for log output\n *\n */\nexport function logChatPromiseExecution<T>(promise: Promise<T>, name: string) {\n promise.then().catch((error) => {\n console.warn(`failed to do ${name}, ran into error: `, error);\n });\n}\n\nexport const sleep = (m: number): Promise<void> => new Promise((r) => setTimeout(r, m));\n\nexport function isFunction<T>(value: Function | T): value is Function {\n return (\n value &&\n (Object.prototype.toString.call(value) === '[object Function]' ||\n 'function' === typeof value ||\n value instanceof Function)\n );\n}\n\nexport const chatCodes = {\n TOKEN_EXPIRED: 40,\n WS_CLOSED_SUCCESS: 1000,\n};\n\nfunction isReadableStream(obj: unknown): obj is NodeJS.ReadStream {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function')\n );\n}\n\nfunction isBuffer(obj: unknown): obj is Buffer {\n return (\n obj != null &&\n (obj as Buffer).constructor != null &&\n // @ts-expect-error\n typeof obj.constructor.isBuffer === 'function' &&\n // @ts-expect-error\n obj.constructor.isBuffer(obj)\n );\n}\n\nfunction isFileWebAPI(uri: unknown): uri is File {\n return typeof window !== 'undefined' && 'File' in window && uri instanceof File;\n}\n\nexport function isOwnUser<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>,\n): user is OwnUserResponse<StreamChatGenerics> {\n return (user as OwnUserResponse<StreamChatGenerics>)?.total_unread_count !== undefined;\n}\n\nfunction isBlobWebAPI(uri: unknown): uri is Blob {\n return typeof window !== 'undefined' && 'Blob' in window && uri instanceof Blob;\n}\n\nexport function isOwnUserBaseProperty(property: string) {\n const ownUserBaseProperties: {\n [Property in keyof Required<OwnUserBase>]: boolean;\n } = {\n channel_mutes: true,\n devices: true,\n mutes: true,\n total_unread_count: true,\n unread_channels: true,\n unread_count: true,\n unread_threads: true,\n invisible: true,\n privacy_settings: true,\n roles: true,\n };\n\n return ownUserBaseProperties[property as keyof OwnUserBase];\n}\n\nexport function addFileToFormData(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n) {\n const data = new FormData();\n\n if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {\n if (name) data.append('file', uri, name);\n else data.append('file', uri);\n } else {\n data.append('file', {\n uri,\n name: name || (uri as string).split('/').reverse()[0],\n contentType: contentType || undefined,\n type: contentType || undefined,\n });\n }\n\n return data;\n}\nexport function normalizeQuerySort<T extends Record<string, AscDesc | undefined>>(sort: T | T[]) {\n const sortFields: Array<{ direction: AscDesc; field: keyof T }> = [];\n const sortArr = Array.isArray(sort) ? sort : [sort];\n for (const item of sortArr) {\n const entries = Object.entries(item) as [keyof T, AscDesc][];\n if (entries.length > 1) {\n console.warn(\n \"client._buildSort() - multiple fields in a single sort object detected. Object's field order is not guaranteed\",\n );\n }\n for (const [field, direction] of entries) {\n sortFields.push({ field, direction });\n }\n }\n return sortFields;\n}\n\n/**\n * retryInterval - A retry interval which increases acc to number of failures\n *\n * @return {number} Duration to wait in milliseconds\n */\nexport function retryInterval(numberOfFailures: number) {\n // try to reconnect in 0.25-25 seconds (random to spread out the load from failures)\n const max = Math.min(500 + numberOfFailures * 2000, 25000);\n const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2000), 25000);\n return Math.floor(Math.random() * (max - min) + min);\n}\n\nexport function randomId() {\n return generateUUIDv4();\n}\n\nfunction hex(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0');\n }\n return s;\n}\n\n// https://tools.ietf.org/html/rfc4122\nexport function generateUUIDv4() {\n const bytes = getRandomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant\n\n return (\n hex(bytes.subarray(0, 4)) +\n '-' +\n hex(bytes.subarray(4, 6)) +\n '-' +\n hex(bytes.subarray(6, 8)) +\n '-' +\n hex(bytes.subarray(8, 10)) +\n '-' +\n hex(bytes.subarray(10, 16))\n );\n}\n\nfunction getRandomValuesWithMathRandom(bytes: Uint8Array): void {\n const max = Math.pow(2, (8 * bytes.byteLength) / bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.random() * max;\n }\n}\ndeclare const msCrypto: Crypto;\n\nconst getRandomValues = (() => {\n if (typeof crypto !== 'undefined' && typeof crypto?.getRandomValues !== 'undefined') {\n return crypto.getRandomValues.bind(crypto);\n } else if (typeof msCrypto !== 'undefined') {\n return msCrypto.getRandomValues.bind(msCrypto);\n } else {\n return getRandomValuesWithMathRandom;\n }\n})();\n\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getRandomValues(bytes);\n return bytes;\n}\n\nexport function convertErrorToJson(err: Error) {\n const jsonObj = {} as Record<string, unknown>;\n\n if (!err) return jsonObj;\n\n try {\n Object.getOwnPropertyNames(err).forEach((key) => {\n jsonObj[key] = Object.getOwnPropertyDescriptor(err, key);\n });\n } catch (_) {\n return {\n error: 'failed to serialize the error',\n };\n }\n\n return jsonObj;\n}\n\n/**\n * isOnline safely return the navigator.online value for browser env\n * if navigator is not in global object, it always return true\n */\nexport function isOnline() {\n const nav =\n typeof navigator !== 'undefined'\n ? navigator\n : typeof window !== 'undefined' && window.navigator\n ? window.navigator\n : undefined;\n\n if (!nav) {\n console.warn('isOnline failed to access window.navigator and assume browser is online');\n return true;\n }\n\n // RN navigator has undefined for onLine\n if (typeof nav.onLine !== 'boolean') {\n return true;\n }\n\n return nav.onLine;\n}\n\n/**\n * listenForConnectionChanges - Adds an event listener fired on browser going online or offline\n */\nexport function addConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('offline', cb);\n window.addEventListener('online', cb);\n }\n}\n\nexport function removeConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.removeEventListener) {\n window.removeEventListener('offline', cb);\n window.removeEventListener('online', cb);\n }\n}\n\nexport const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (params) => {\n const newParams = [];\n for (const k in params) {\n // Stream backend doesn't treat \"undefined\" value same as value not being present.\n // So, we need to skip the undefined values.\n if (params[k] === undefined) continue;\n\n if (Array.isArray(params[k]) || typeof params[k] === 'object') {\n newParams.push(`${k}=${encodeURIComponent(JSON.stringify(params[k]))}`);\n } else {\n newParams.push(`${k}=${encodeURIComponent(params[k])}`);\n }\n }\n\n return newParams.join('&');\n};\n\n/**\n * Takes the message object, parses the dates, sets `__html`\n * and sets the status to `received` if missing; returns a new message object.\n *\n * @param {MessageResponse<StreamChatGenerics>} message `MessageResponse` object\n */\nexport function formatMessage<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: MessageResponse<StreamChatGenerics> | FormatMessageResponse<StreamChatGenerics>,\n): FormatMessageResponse<StreamChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the dates\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),\n deleted_at: message.deleted_at ? new Date(message.deleted_at) : null,\n status: message.status || 'received',\n reaction_groups: maybeGetReactionGroupsFallback(\n message.reaction_groups,\n message.reaction_counts,\n message.reaction_scores,\n ),\n };\n}\n\nexport const findIndexInSortedArray = <T, L>({\n needle,\n sortedArray,\n selectValueToCompare = (e) => e,\n sortDirection = 'ascending',\n}: {\n needle: T;\n sortedArray: readonly T[];\n /**\n * In array of objects (like messages), pick a specific\n * property to compare needle value to.\n *\n * @example\n * ```ts\n * selectValueToCompare: (message) => message.created_at.getTime()\n * ```\n */\n selectValueToCompare?: (arrayElement: T) => L | T;\n /**\n * @default ascending\n * @description\n * ```md\n * ascending - [1,2,3,4,5...]\n * descending - [...5,4,3,2,1]\n * ```\n */\n sortDirection?: 'ascending' | 'descending';\n}) => {\n if (!sortedArray.length) return 0;\n\n let left = 0;\n let right = sortedArray.length - 1;\n let middle = 0;\n\n const recalculateMiddle = () => {\n middle = Math.round((left + right) / 2);\n };\n\n const comparableNeedle = selectValueToCompare(needle);\n\n while (left <= right) {\n recalculateMiddle();\n\n const comparableMiddle = selectValueToCompare(sortedArray[middle]);\n\n // if (comparableNeedle === comparableMiddle) return middle;\n\n if (\n (sortDirection === 'ascending' && comparableNeedle < comparableMiddle) ||\n (sortDirection === 'descending' && comparableNeedle > comparableMiddle)\n ) {\n right = middle - 1;\n } else {\n left = middle + 1;\n }\n }\n\n return left;\n};\n\nexport function addToMessageList<T extends FormatMessageResponse>(\n messages: readonly T[],\n newMessage: T,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n) {\n const addMessageToList = addIfDoesNotExist || timestampChanged;\n let newMessages = [...messages];\n\n // if created_at has changed, message should be filtered and re-inserted in correct order\n // slow op but usually this only happens for a message inserted to state before actual response with correct timestamp\n if (timestampChanged) {\n newMessages = newMessages.filter((message) => !(message.id && newMessage.id === message.id));\n }\n\n // for empty list just concat and return unless it's an update or deletion\n if (newMessages.length === 0 && addMessageToList) {\n return newMessages.concat(newMessage);\n } else if (newMessages.length === 0) {\n return newMessages;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const messageTime = newMessage[sortBy]!.getTime();\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const messageIsNewest = newMessages.at(-1)![sortBy]!.getTime() < messageTime;\n\n // if message is newer than last item in the list concat and return unless it's an update or deletion\n if (messageIsNewest && addMessageToList) {\n return newMessages.concat(newMessage);\n } else if (messageIsNewest) {\n return newMessages;\n }\n\n // find the closest index to push the new message\n const insertionIndex = findIndexInSortedArray({\n needle: newMessage,\n sortedArray: newMessages,\n sortDirection: 'ascending',\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n selectValueToCompare: (m) => m[sortBy]!.getTime(),\n });\n\n // message already exists and not filtered with timestampChanged, update and return\n if (!timestampChanged && newMessage.id) {\n if (newMessages[insertionIndex] && newMessage.id === newMessages[insertionIndex].id) {\n newMessages[insertionIndex] = newMessage;\n return newMessages;\n }\n\n if (newMessages[insertionIndex - 1] && newMessage.id === newMessages[insertionIndex - 1].id) {\n newMessages[insertionIndex - 1] = newMessage;\n return newMessages;\n }\n }\n\n // do not add updated or deleted messages to the list if they already exist or come with a timestamp change\n if (addMessageToList) {\n newMessages.splice(insertionIndex, 0, newMessage);\n }\n\n return newMessages;\n}\n\nfunction maybeGetReactionGroupsFallback(\n groups: { [key: string]: ReactionGroupResponse } | null | undefined,\n counts: { [key: string]: number } | null | undefined,\n scores: { [key: string]: number } | null | undefined,\n): { [key: string]: ReactionGroupResponse } | null {\n if (groups) {\n return groups;\n }\n\n if (counts && scores) {\n const fallback: { [key: string]: ReactionGroupResponse } = {};\n\n for (const type of Object.keys(counts)) {\n fallback[type] = {\n count: counts[type],\n sum_scores: scores[type],\n };\n }\n\n return fallback;\n }\n\n return null;\n}\n\n// works exactly the same as lodash.throttle\nexport const throttle = <T extends (...args: unknown[]) => unknown>(\n fn: T,\n timeout = 200,\n { leading = true, trailing = false }: { leading?: boolean; trailing?: boolean } = {},\n) => {\n let runningTimeout: null | NodeJS.Timeout = null;\n let storedArgs: Parameters<T> | null = null;\n\n return (...args: Parameters<T>) => {\n if (runningTimeout) {\n if (trailing) storedArgs = args;\n return;\n }\n\n if (leading) fn(...args);\n\n const timeoutHandler = () => {\n if (storedArgs) {\n fn(...storedArgs);\n storedArgs = null;\n runningTimeout = setTimeout(timeoutHandler, timeout);\n\n return;\n }\n\n runningTimeout = null;\n };\n\n runningTimeout = setTimeout(timeoutHandler, timeout);\n };\n};\n\ntype MessagePaginationUpdatedParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n parentSet: MessageSet;\n requestedPageSize: number;\n returnedPage: MessageResponse<StreamChatGenerics>[];\n logger?: Logger;\n messagePaginationOptions?: MessagePaginationOptions;\n};\n\nexport function binarySearchByDateEqualOrNearestGreater(\n array: {\n created_at?: string;\n }[],\n targetDate: Date,\n): number {\n let left = 0;\n let right = array.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const midCreatedAt = array[mid].created_at;\n if (!midCreatedAt) {\n left += 1;\n continue;\n }\n const midDate = new Date(midCreatedAt);\n\n if (midDate.getTime() === targetDate.getTime()) {\n return mid;\n } else if (midDate.getTime() < targetDate.getTime()) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return left;\n}\n\nconst messagePaginationCreatedAtAround = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n if (!messagePaginationOptions?.created_at_around) return newPagination;\n let hasPrev;\n let hasNext;\n let updateHasPrev;\n let updateHasNext;\n const createdAtAroundDate = new Date(messagePaginationOptions.created_at_around);\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n\n // expect ASC order (from oldest to newest)\n const wholePageHasNewerMessages =\n !!firstPageMsg?.created_at && new Date(firstPageMsg.created_at) > createdAtAroundDate;\n const wholePageHasOlderMessages = !!lastPageMsg?.created_at && new Date(lastPageMsg.created_at) < createdAtAroundDate;\n\n const requestedPageSizeNotMet =\n requestedPageSize > parentSet.messages.length && requestedPageSize > returnedPage.length;\n const noMoreMessages =\n (requestedPageSize > parentSet.messages.length || parentSet.messages.length >= returnedPage.length) &&\n requestedPageSize > returnedPage.length;\n\n if (wholePageHasNewerMessages) {\n hasPrev = false;\n updateHasPrev = true;\n if (requestedPageSizeNotMet) {\n hasNext = false;\n updateHasNext = true;\n }\n } else if (wholePageHasOlderMessages) {\n hasNext = false;\n updateHasNext = true;\n if (requestedPageSizeNotMet) {\n hasPrev = false;\n updateHasPrev = true;\n }\n } else if (noMoreMessages) {\n hasNext = hasPrev = false;\n updateHasPrev = updateHasNext = true;\n } else {\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id && firstPageMsg.id === parentSet.messages[0]?.id,\n lastPageMsg?.id && lastPageMsg.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n updateHasPrev = firstPageMsgIsFirstInSet;\n updateHasNext = lastPageMsgIsLastInSet;\n const midPointByCount = Math.floor(returnedPage.length / 2);\n const midPointByCreationDate = binarySearchByDateEqualOrNearestGreater(returnedPage, createdAtAroundDate);\n\n if (midPointByCreationDate !== -1) {\n hasPrev = midPointByCount <= midPointByCreationDate;\n hasNext = midPointByCount >= midPointByCreationDate;\n }\n }\n\n if (updateHasPrev && typeof hasPrev !== 'undefined') newPagination.hasPrev = hasPrev;\n if (updateHasNext && typeof hasNext !== 'undefined') newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nconst messagePaginationIdAround = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n const { id_around } = messagePaginationOptions || {};\n if (!id_around) return newPagination;\n let hasPrev;\n let hasNext;\n\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id === parentSet.messages[0]?.id,\n lastPageMsg?.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n let updateHasPrev = firstPageMsgIsFirstInSet;\n let updateHasNext = lastPageMsgIsLastInSet;\n\n const midPoint = Math.floor(returnedPage.length / 2);\n const noMoreMessages =\n (requestedPageSize > parentSet.messages.length || parentSet.messages.length >= returnedPage.length) &&\n requestedPageSize > returnedPage.length;\n\n if (noMoreMessages) {\n hasNext = hasPrev = false;\n updateHasPrev = updateHasNext = true;\n } else if (!returnedPage[midPoint]) {\n return newPagination;\n } else if (returnedPage[midPoint].id === id_around) {\n hasPrev = hasNext = true;\n } else {\n let targetMsg;\n const halves = [returnedPage.slice(0, midPoint), returnedPage.slice(midPoint)];\n hasPrev = hasNext = true;\n for (let i = 0; i < halves.length; i++) {\n targetMsg = halves[i].find((message) => message.id === id_around);\n if (targetMsg && i === 0) {\n hasPrev = false;\n }\n if (targetMsg && i === 1) {\n hasNext = false;\n }\n }\n }\n\n if (updateHasPrev && typeof hasPrev !== 'undefined') newPagination.hasPrev = hasPrev;\n if (updateHasNext && typeof hasNext !== 'undefined') newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nconst messagePaginationLinear = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n\n let hasPrev;\n let hasNext;\n\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id && firstPageMsg.id === parentSet.messages[0]?.id,\n lastPageMsg?.id && lastPageMsg.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n\n const queriedNextMessages =\n messagePaginationOptions &&\n (messagePaginationOptions.created_at_after_or_equal ||\n messagePaginationOptions.created_at_after ||\n messagePaginationOptions.id_gt ||\n messagePaginationOptions.id_gte);\n\n const queriedPrevMessages =\n typeof messagePaginationOptions === 'undefined'\n ? true\n : messagePaginationOptions.created_at_before_or_equal ||\n messagePaginationOptions.created_at_before ||\n messagePaginationOptions.id_lt ||\n messagePaginationOptions.id_lte ||\n messagePaginationOptions.offset;\n\n const containsUnrecognizedOptionsOnly =\n !queriedNextMessages &&\n !queriedPrevMessages &&\n !messagePaginationOptions?.id_around &&\n !messagePaginationOptions?.created_at_around;\n\n const hasMore = returnedPage.length >= requestedPageSize;\n\n if (typeof queriedPrevMessages !== 'undefined' || containsUnrecognizedOptionsOnly) {\n hasPrev = hasMore;\n }\n if (typeof queriedNextMessages !== 'undefined') {\n hasNext = hasMore;\n }\n const returnedPageIsEmpty = returnedPage.length === 0;\n\n if ((firstPageMsgIsFirstInSet || returnedPageIsEmpty) && typeof hasPrev !== 'undefined')\n newPagination.hasPrev = hasPrev;\n if ((lastPageMsgIsLastInSet || returnedPageIsEmpty) && typeof hasNext !== 'undefined')\n newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nexport const messageSetPagination = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n params: MessagePaginationUpdatedParams<StreamChatGenerics>,\n) => {\n if (params.parentSet.messages.length < params.returnedPage.length) {\n params.logger?.('error', 'Corrupted message set state: parent set size < returned page size');\n return params.parentSet.pagination;\n }\n\n if (params.messagePaginationOptions?.created_at_around) {\n return messagePaginationCreatedAtAround(params);\n } else if (params.messagePaginationOptions?.id_around) {\n return messagePaginationIdAround(params);\n } else {\n return messagePaginationLinear(params);\n }\n};\n","export const DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE = 25;\nexport const DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE = 100;\n\nexport const DEFAULT_MESSAGE_SET_PAGINATION = { hasNext: true, hasPrev: true };\n","import { Channel } from './channel';\nimport {\n ChannelMemberResponse,\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n FormatMessageResponse,\n MessageResponse,\n MessageSet,\n MessageSetType,\n PendingMessageResponse,\n ReactionResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList, formatMessage } from './utils';\nimport { DEFAULT_MESSAGE_SET_PAGINATION } from './constants';\n\ntype ChannelReadStatus<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n {\n last_read: Date;\n unread_messages: number;\n user: UserResponse<StreamChatGenerics>;\n first_unread_message_id?: string;\n last_read_message_id?: string;\n }\n>;\n\n/**\n * ChannelState - A container class for the channel state.\n */\nexport class ChannelState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _channel: Channel<StreamChatGenerics>;\n watcher_count: number;\n typing: Record<string, Event<StreamChatGenerics>>;\n read: ChannelReadStatus<StreamChatGenerics>;\n pinnedMessages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>;\n pending_messages: Array<PendingMessageResponse<StreamChatGenerics>>;\n threads: Record<string, Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>>;\n mutedUsers: Array<UserResponse<StreamChatGenerics>>;\n watchers: Record<string, UserResponse<StreamChatGenerics>>;\n members: Record<string, ChannelMemberResponse<StreamChatGenerics>>;\n unreadCount: number;\n membership: ChannelMemberResponse<StreamChatGenerics>;\n last_message_at: Date | null;\n /**\n * Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n isUpToDate: boolean;\n /**\n * Disjoint lists of messages\n * Users can jump in the message list (with searching) and this can result in disjoint lists of messages\n * The state manages these lists and merges them when lists overlap\n * The messages array contains the currently active set\n */\n messageSets: MessageSet[] = [];\n\n constructor(channel: Channel<StreamChatGenerics>) {\n this._channel = channel;\n this.watcher_count = 0;\n this.typing = {};\n this.read = {};\n this.initMessages();\n this.pinnedMessages = [];\n this.pending_messages = [];\n this.threads = {};\n // a list of users to hide messages from\n this.mutedUsers = [];\n this.watchers = {};\n this.members = {};\n this.membership = {};\n this.unreadCount = 0;\n /**\n * Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n this.isUpToDate = true;\n this.last_message_at = channel?.state?.last_message_at != null ? new Date(channel.state.last_message_at) : null;\n }\n\n get messages() {\n return this.messageSets.find((s) => s.isCurrent)?.messages || [];\n }\n\n set messages(messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isCurrent);\n this.messageSets[index].messages = messages;\n }\n\n /**\n * The list of latest messages\n * The messages array not always contains the latest messages (for example if a user searched for an earlier message, that is in a different message set)\n */\n get latestMessages() {\n return this.messageSets.find((s) => s.isLatest)?.messages || [];\n }\n\n set latestMessages(messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isLatest);\n this.messageSets[index].messages = messages;\n }\n\n get messagePagination() {\n return this.messageSets.find((s) => s.isCurrent)?.pagination || DEFAULT_MESSAGE_SET_PAGINATION;\n }\n\n /**\n * addMessageSorted - Add a message to the state\n *\n * @param {MessageResponse<StreamChatGenerics>} newMessage A new message\n * @param {boolean} timestampChanged Whether updating a message with changed created_at value.\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if message is not in the list (only used if addIfDoesNotExist is true)\n */\n addMessageSorted(\n newMessage: MessageResponse<StreamChatGenerics>,\n timestampChanged = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n return this.addMessagesSorted(\n [newMessage],\n timestampChanged,\n false,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n }\n\n /**\n * Takes the message object, parses the dates, sets `__html`\n * and sets the status to `received` if missing; returns a new message object.\n *\n * @param {MessageResponse<StreamChatGenerics>} message `MessageResponse` object\n */\n formatMessage = (message: MessageResponse<StreamChatGenerics>) => formatMessage<StreamChatGenerics>(message);\n\n /**\n * addMessagesSorted - Add the list of messages to state and resorts the messages\n *\n * @param {Array<MessageResponse<StreamChatGenerics>>} newMessages A list of messages\n * @param {boolean} timestampChanged Whether updating messages with changed created_at value.\n * @param {boolean} initializing Whether channel is being initialized.\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if messages are not in the list (only used if addIfDoesNotExist is true)\n *\n */\n addMessagesSorted(\n newMessages: MessageResponse<StreamChatGenerics>[],\n timestampChanged = false,\n initializing = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n const { messagesToAdd, targetMessageSetIndex } = this.findTargetMessageSet(\n newMessages,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n\n for (let i = 0; i < messagesToAdd.length; i += 1) {\n const isFromShadowBannedUser = messagesToAdd[i].shadowed;\n if (isFromShadowBannedUser) {\n continue;\n }\n // If message is already formatted we can skip the tasks below\n // This will be true for messages that are already present at the state -> this happens when we perform merging of message sets\n // This will be also true for message previews used by some SDKs\n const isMessageFormatted = messagesToAdd[i].created_at instanceof Date;\n let message: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n if (isMessageFormatted) {\n message = messagesToAdd[i] as ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n } else {\n message = this.formatMessage(messagesToAdd[i] as MessageResponse<StreamChatGenerics>);\n\n if (message.user && this._channel?.cid) {\n /**\n * Store the reference to user for this channel, so that when we have to\n * handle updates to user, we can use the reference map, to determine which\n * channels need to be updated with updated user object.\n */\n this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);\n }\n\n if (initializing && message.id && this.threads[message.id]) {\n // If we are initializing the state of channel (e.g., in case of connection recovery),\n // then in that case we remove thread related to this message from threads object.\n // This way we can ensure that we don't have any stale data in thread object\n // and consumer can refetch the replies.\n delete this.threads[message.id];\n }\n\n if (!this.last_message_at) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n\n if (message.created_at.getTime() > this.last_message_at.getTime()) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n }\n\n // update or append the messages...\n const parentID = message.parent_id;\n\n // add to the given message set\n if ((!parentID || message.show_in_channel) && targetMessageSetIndex !== -1) {\n this.messageSets[targetMessageSetIndex].messages = this._addToMessageList(\n this.messageSets[targetMessageSetIndex].messages,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n\n /**\n * Add message to thread if applicable and the message\n * was added when querying for replies, or the thread already exits.\n * This is to prevent the thread state from getting out of sync if\n * a thread message is shown in channel but older than the newest thread\n * message. This situation can result in a thread state where a random\n * message is \"oldest\" message, and newer messages are therefore not loaded.\n * This can also occur if an old thread message is updated.\n */\n if (parentID && !initializing) {\n const thread = this.threads[parentID] || [];\n this.threads[parentID] = this._addToMessageList(\n thread,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n }\n\n return {\n messageSet: this.messageSets[targetMessageSetIndex],\n };\n }\n\n /**\n * addPinnedMessages - adds messages in pinnedMessages property\n *\n * @param {Array<MessageResponse<StreamChatGenerics>>} pinnedMessages A list of pinned messages\n *\n */\n addPinnedMessages(pinnedMessages: MessageResponse<StreamChatGenerics>[]) {\n for (let i = 0; i < pinnedMessages.length; i += 1) {\n this.addPinnedMessage(pinnedMessages[i]);\n }\n }\n\n /**\n * addPinnedMessage - adds message in pinnedMessages\n *\n * @param {MessageResponse<StreamChatGenerics>} pinnedMessage message to update\n *\n */\n addPinnedMessage(pinnedMessage: MessageResponse<StreamChatGenerics>) {\n this.pinnedMessages = this._addToMessageList(\n this.pinnedMessages,\n this.formatMessage(pinnedMessage),\n false,\n 'pinned_at',\n );\n }\n\n /**\n * removePinnedMessage - removes pinned message from pinnedMessages\n *\n * @param {MessageResponse<StreamChatGenerics>} message message to remove\n *\n */\n removePinnedMessage(message: MessageResponse<StreamChatGenerics>) {\n const { result } = this.removeMessageFromArray(this.pinnedMessages, message);\n this.pinnedMessages = result;\n }\n\n addReaction(\n reaction: ReactionResponse<StreamChatGenerics>,\n message?: MessageResponse<StreamChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._addOwnReactionToMessage(msg.own_reactions, reaction, enforce_unique);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _addOwnReactionToMessage(\n ownReactions: ReactionResponse<StreamChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<StreamChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (enforce_unique) {\n ownReactions = [];\n } else {\n ownReactions = this._removeOwnReactionFromMessage(ownReactions, reaction);\n }\n\n ownReactions = ownReactions || [];\n if (this._channel.getClient().userID === reaction.user_id) {\n ownReactions.push(reaction);\n }\n\n return ownReactions;\n }\n\n _removeOwnReactionFromMessage(\n ownReactions: ReactionResponse<StreamChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<StreamChatGenerics>,\n ) {\n if (ownReactions) {\n return ownReactions.filter((item) => item.user_id !== reaction.user_id || item.type !== reaction.type);\n }\n return ownReactions;\n }\n\n removeReaction(reaction: ReactionResponse<StreamChatGenerics>, message?: MessageResponse<StreamChatGenerics>) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._removeOwnReactionFromMessage(msg.own_reactions, reaction);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _updateQuotedMessageReferences({\n message,\n remove,\n }: {\n message: MessageResponse<StreamChatGenerics>;\n remove?: boolean;\n }) {\n const parseMessage = (m: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>) =>\n (({\n ...m,\n created_at: m.created_at.toISOString(),\n pinned_at: m.pinned_at?.toISOString(),\n updated_at: m.updated_at?.toISOString(),\n } as unknown) as MessageResponse<StreamChatGenerics>);\n\n const update = (messages: FormatMessageResponse<StreamChatGenerics>[]) => {\n const updatedMessages = messages.reduce<MessageResponse<StreamChatGenerics>[]>((acc, msg) => {\n if (msg.quoted_message_id === message.id) {\n acc.push({ ...parseMessage(msg), quoted_message: remove ? { ...message, attachments: [] } : message });\n }\n return acc;\n }, []);\n this.addMessagesSorted(updatedMessages, true);\n };\n\n if (!message.parent_id) {\n this.messageSets.forEach((set) => update(set.messages));\n } else if (message.parent_id && this.threads[message.parent_id]) {\n // prevent going through all the threads even though it is possible to quote a message from another thread\n update(this.threads[message.parent_id]);\n }\n }\n\n removeQuotedMessageReferences(message: MessageResponse<StreamChatGenerics>) {\n this._updateQuotedMessageReferences({ message, remove: true });\n }\n\n /**\n * Updates all instances of given message in channel state\n * @param message\n * @param updateFunc\n */\n _updateMessage(\n message: {\n id?: string;\n parent_id?: string;\n pinned?: boolean;\n show_in_channel?: boolean;\n },\n updateFunc: (\n msg: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n ) => ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n ) {\n const { parent_id, show_in_channel, pinned } = message;\n\n if (parent_id && this.threads[parent_id]) {\n const thread = this.threads[parent_id];\n const msgIndex = thread.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n thread[msgIndex] = updateFunc(thread[msgIndex]);\n this.threads[parent_id] = thread;\n }\n }\n\n if ((!show_in_channel && !parent_id) || show_in_channel) {\n const messageSetIndex = this.findMessageSetIndex(message);\n if (messageSetIndex !== -1) {\n const msgIndex = this.messageSets[messageSetIndex].messages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.messageSets[messageSetIndex].messages[msgIndex] = updateFunc(\n this.messageSets[messageSetIndex].messages[msgIndex],\n );\n }\n }\n }\n\n if (pinned) {\n const msgIndex = this.pinnedMessages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.pinnedMessages[msgIndex] = updateFunc(this.pinnedMessages[msgIndex]);\n }\n }\n }\n\n /**\n * Setter for isUpToDate.\n *\n * @param isUpToDate Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n setIsUpToDate = (isUpToDate: boolean) => {\n this.isUpToDate = isUpToDate;\n };\n\n /**\n * _addToMessageList - Adds a message to a list of messages, tries to update first, appends if message isn't found\n *\n * @param {Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>} messages A list of messages\n * @param message\n * @param {boolean} timestampChanged Whether updating a message with changed created_at value.\n * @param {string} sortBy field name to use to sort the messages by\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n */\n _addToMessageList(\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n message: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n ) {\n return addToMessageList(messages, message, timestampChanged, sortBy, addIfDoesNotExist);\n }\n\n /**\n * removeMessage - Description\n *\n * @param {{ id: string; parent_id?: string }} messageToRemove Object of the message to remove. Needs to have at id specified.\n *\n * @return {boolean} Returns if the message was removed\n */\n removeMessage(messageToRemove: { id: string; messageSetIndex?: number; parent_id?: string }) {\n let isRemoved = false;\n if (messageToRemove.parent_id && this.threads[messageToRemove.parent_id]) {\n const { removed, result: threadMessages } = this.removeMessageFromArray(\n this.threads[messageToRemove.parent_id],\n messageToRemove,\n );\n\n this.threads[messageToRemove.parent_id] = threadMessages;\n isRemoved = removed;\n } else {\n const messageSetIndex = messageToRemove.messageSetIndex ?? this.findMessageSetIndex(messageToRemove);\n if (messageSetIndex !== -1) {\n const { removed, result: messages } = this.removeMessageFromArray(\n this.messageSets[messageSetIndex].messages,\n messageToRemove,\n );\n this.messageSets[messageSetIndex].messages = messages;\n isRemoved = removed;\n }\n }\n\n return isRemoved;\n }\n\n removeMessageFromArray = (\n msgArray: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n msg: { id: string; parent_id?: string },\n ) => {\n const result = msgArray.filter((message) => !(!!message.id && !!msg.id && message.id === msg.id));\n\n return { removed: result.length < msgArray.length, result };\n };\n\n /**\n * Updates the message.user property with updated user object, for messages.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n updateUserMessages = (user: UserResponse<StreamChatGenerics>) => {\n const _updateUserMessages = (\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n user: UserResponse<StreamChatGenerics>,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id === user.id) {\n messages[i] = { ...m, user };\n }\n }\n };\n\n this.messageSets.forEach((set) => _updateUserMessages(set.messages, user));\n\n for (const parentId in this.threads) {\n _updateUserMessages(this.threads[parentId], user);\n }\n\n _updateUserMessages(this.pinnedMessages, user);\n };\n\n /**\n * Marks the messages as deleted, from deleted user.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n * @param {boolean} hardDelete\n */\n deleteUserMessages = (user: UserResponse<StreamChatGenerics>, hardDelete = false) => {\n const _deleteUserMessages = (\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n user: UserResponse<StreamChatGenerics>,\n hardDelete = false,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id !== user.id) {\n continue;\n }\n\n if (hardDelete) {\n /**\n * In case of hard delete, we need to strip down all text, html,\n * attachments and all the custom properties on message\n */\n messages[i] = ({\n cid: m.cid,\n created_at: m.created_at,\n deleted_at: user.deleted_at,\n id: m.id,\n latest_reactions: [],\n mentioned_users: [],\n own_reactions: [],\n parent_id: m.parent_id,\n reply_count: m.reply_count,\n status: m.status,\n thread_participants: m.thread_participants,\n type: 'deleted',\n updated_at: m.updated_at,\n user: m.user,\n } as unknown) as ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n } else {\n messages[i] = {\n ...m,\n type: 'deleted',\n deleted_at: user.deleted_at ? new Date(user.deleted_at) : null,\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _deleteUserMessages(set.messages, user, hardDelete));\n\n for (const parentId in this.threads) {\n _deleteUserMessages(this.threads[parentId], user, hardDelete);\n }\n\n _deleteUserMessages(this.pinnedMessages, user, hardDelete);\n };\n\n /**\n * filterErrorMessages - Removes error messages from the channel state.\n *\n */\n filterErrorMessages() {\n const filteredMessages = this.latestMessages.filter((message) => message.type !== 'error');\n\n this.latestMessages = filteredMessages;\n }\n\n /**\n * clean - Remove stale data such as users that stayed in typing state for more than 5 seconds\n */\n clean() {\n const now = new Date();\n // prevent old users from showing up as typing\n for (const [userID, lastEvent] of Object.entries(this.typing)) {\n const receivedAt =\n typeof lastEvent.received_at === 'string'\n ? new Date(lastEvent.received_at)\n : lastEvent.received_at || new Date();\n if (now.getTime() - receivedAt.getTime() > 7000) {\n delete this.typing[userID];\n this._channel.getClient().dispatchEvent({\n cid: this._channel.cid,\n type: 'typing.stop',\n user: { id: userID },\n } as Event<StreamChatGenerics>);\n }\n }\n }\n\n clearMessages() {\n this.initMessages();\n this.pinnedMessages = [];\n }\n\n initMessages() {\n this.messageSets = [{ messages: [], isLatest: true, isCurrent: true, pagination: DEFAULT_MESSAGE_SET_PAGINATION }];\n }\n\n /**\n * loadMessageIntoState - Loads a given message (and messages around it) into the state\n *\n * @param {string} messageId The id of the message, or 'latest' to indicate switching to the latest messages\n * @param {string} parentMessageId The id of the parent message, if we want load a thread reply\n * @param {number} limit The page size if the message has to be queried from the server\n */\n async loadMessageIntoState(messageId: string | 'latest', parentMessageId?: string, limit = 25) {\n let messageSetIndex: number;\n let switchedToMessageSet = false;\n let loadedMessageThread = false;\n const messageIdToFind = parentMessageId || messageId;\n if (messageId === 'latest') {\n if (this.messages === this.latestMessages) {\n return;\n }\n messageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n } else {\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n }\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n switchedToMessageSet = true;\n }\n loadedMessageThread = !parentMessageId || !!this.threads[parentMessageId]?.find((m) => m.id === messageId);\n if (switchedToMessageSet && loadedMessageThread) {\n return;\n }\n if (!switchedToMessageSet) {\n await this._channel.query({ messages: { id_around: messageIdToFind, limit } }, 'new');\n }\n if (!loadedMessageThread && parentMessageId) {\n await this._channel.getReplies(parentMessageId, { id_around: messageId, limit });\n }\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n }\n }\n\n /**\n * findMessage - Finds a message inside the state\n *\n * @param {string} messageId The id of the message\n * @param {string} parentMessageId The id of the parent message, if we want load a thread reply\n *\n * @return {ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>} Returns the message, or undefined if the message wasn't found\n */\n findMessage(messageId: string, parentMessageId?: string) {\n if (parentMessageId) {\n const messages = this.threads[parentMessageId];\n if (!messages) {\n return undefined;\n }\n return messages.find((m) => m.id === messageId);\n }\n\n const messageSetIndex = this.findMessageSetIndex({ id: messageId });\n if (messageSetIndex === -1) {\n return undefined;\n }\n return this.messageSets[messageSetIndex].messages.find((m) => m.id === messageId);\n }\n\n private switchToMessageSet(index: number) {\n const currentMessages = this.messageSets.find((s) => s.isCurrent);\n if (!currentMessages) {\n return;\n }\n currentMessages.isCurrent = false;\n this.messageSets[index].isCurrent = true;\n }\n\n private areMessageSetsOverlap(messages1: Array<{ id: string }>, messages2: Array<{ id: string }>) {\n return messages1.some((m1) => messages2.find((m2) => m1.id === m2.id));\n }\n\n private findMessageSetIndex(message: { id?: string }) {\n return this.messageSets.findIndex((set) => !!set.messages.find((m) => m.id === message.id));\n }\n\n private findTargetMessageSet(\n newMessages: MessageResponse<StreamChatGenerics>[],\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n let messagesToAdd: (\n | MessageResponse<StreamChatGenerics>\n | ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>\n )[] = newMessages;\n let targetMessageSetIndex!: number;\n if (addIfDoesNotExist) {\n const overlappingMessageSetIndices = this.messageSets\n .map((_, i) => i)\n .filter((i) => this.areMessageSetsOverlap(this.messageSets[i].messages, newMessages));\n switch (messageSetToAddToIfDoesNotExist) {\n case 'new':\n if (overlappingMessageSetIndices.length > 0) {\n targetMessageSetIndex = overlappingMessageSetIndices[0];\n // No new message set is created if newMessages only contains thread replies\n } else if (newMessages.some((m) => !m.parent_id)) {\n this.messageSets.push({\n messages: [],\n isCurrent: false,\n isLatest: false,\n pagination: DEFAULT_MESSAGE_SET_PAGINATION,\n });\n targetMessageSetIndex = this.messageSets.length - 1;\n }\n break;\n case 'current':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isCurrent);\n break;\n case 'latest':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n break;\n default:\n targetMessageSetIndex = -1;\n }\n // when merging the target set will be the first one from the overlapping message sets\n const mergeTargetMessageSetIndex = overlappingMessageSetIndices.splice(0, 1)[0];\n const mergeSourceMessageSetIndices = [...overlappingMessageSetIndices];\n if (mergeTargetMessageSetIndex !== undefined && mergeTargetMessageSetIndex !== targetMessageSetIndex) {\n mergeSourceMessageSetIndices.push(targetMessageSetIndex);\n }\n // merge message sets\n if (mergeSourceMessageSetIndices.length > 0) {\n const target = this.messageSets[mergeTargetMessageSetIndex];\n const sources = this.messageSets.filter((_, i) => mergeSourceMessageSetIndices.indexOf(i) !== -1);\n sources.forEach((messageSet) => {\n target.isLatest = target.isLatest || messageSet.isLatest;\n target.isCurrent = target.isCurrent || messageSet.isCurrent;\n target.pagination.hasPrev =\n messageSet.messages[0].created_at < target.messages[0].created_at\n ? messageSet.pagination.hasPrev\n : target.pagination.hasPrev;\n target.pagination.hasNext =\n target.messages.slice(-1)[0].created_at < messageSet.messages.slice(-1)[0].created_at\n ? messageSet.pagination.hasNext\n : target.pagination.hasNext;\n messagesToAdd = [...messagesToAdd, ...messageSet.messages];\n });\n sources.forEach((s) => this.messageSets.splice(this.messageSets.indexOf(s), 1));\n const overlappingMessageSetIndex = this.messageSets.findIndex((s) =>\n this.areMessageSetsOverlap(s.messages, newMessages),\n );\n targetMessageSetIndex = overlappingMessageSetIndex;\n }\n } else {\n // assumes that all new messages belong to the same set\n targetMessageSetIndex = this.findMessageSetIndex(newMessages[0]);\n }\n\n return { targetMessageSetIndex, messagesToAdd };\n }\n}\n","import { ChannelState } from './channel_state';\nimport { logChatPromiseExecution, messageSetPagination, normalizeQuerySort } from './utils';\nimport { StreamChat } from './client';\nimport {\n APIResponse,\n BanUserOptions,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelMemberAPIResponse,\n ChannelMemberResponse,\n ChannelQueryOptions,\n ChannelResponse,\n ChannelUpdateOptions,\n CreateCallOptions,\n CreateCallResponse,\n DefaultGenerics,\n DeleteChannelAPIResponse,\n Event,\n EventAPIResponse,\n EventHandler,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n GetMultipleMessagesAPIResponse,\n GetReactionsAPIResponse,\n GetRepliesAPIResponse,\n InviteOptions,\n MarkReadOptions,\n MarkUnreadOptions,\n MemberFilters,\n MemberSort,\n Message,\n MessageFilters,\n MessagePaginationOptions,\n MessageResponse,\n MessageSetType,\n MuteChannelAPIResponse,\n NewMemberPayload,\n PartialUpdateChannel,\n PartialUpdateChannelAPIResponse,\n PartialUpdateMember,\n PinnedMessagePaginationOptions,\n PinnedMessagesSort,\n QueryMembersOptions,\n Reaction,\n ReactionAPIResponse,\n SearchAPIResponse,\n SearchMessageSortBase,\n SearchOptions,\n SearchPayload,\n SendMessageAPIResponse,\n TruncateChannelAPIResponse,\n TruncateOptions,\n UpdateChannelAPIResponse,\n UserResponse,\n QueryChannelAPIResponse,\n PollVoteData,\n SendMessageOptions,\n AscDesc,\n PartialUpdateMemberAPIResponse,\n} from './types';\nimport { Role } from './permissions';\nimport { DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE } from './constants';\n\n/**\n * Channel - The Channel class manages it's own state.\n */\nexport class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _client: StreamChat<StreamChatGenerics>;\n type: string;\n id: string | undefined;\n data: ChannelData<StreamChatGenerics> | ChannelResponse<StreamChatGenerics> | undefined;\n _data: ChannelData<StreamChatGenerics> | ChannelResponse<StreamChatGenerics>;\n cid: string;\n /** */\n listeners: { [key: string]: (string | EventHandler<StreamChatGenerics>)[] };\n state: ChannelState<StreamChatGenerics>;\n /**\n * This boolean is a vague indication of weather the channel exists on chat backend.\n *\n * If the value is true, then that means the channel has been initialized by either calling\n * channel.create() or channel.query() or channel.watch().\n *\n * If the value is false, then channel may or may not exist on the backend. The only way to ensure\n * is by calling channel.create() or channel.query() or channel.watch().\n */\n initialized: boolean;\n /**\n * Indicates weather channel has been initialized by manually populating the state with some messages, members etc.\n * Static state indicates that channel exists on backend, but is not being watched yet.\n */\n offlineMode: boolean;\n lastKeyStroke?: Date;\n lastTypingEvent: Date | null;\n isTyping: boolean;\n disconnected: boolean;\n\n /**\n * constructor - Create a channel\n *\n * @param {StreamChat<StreamChatGenerics>} client the chat client\n * @param {string} type the type of channel\n * @param {string} [id] the id of the chat\n * @param {ChannelData<StreamChatGenerics>} data any additional custom params\n *\n * @return {Channel<StreamChatGenerics>} Returns a new uninitialized channel\n */\n constructor(\n client: StreamChat<StreamChatGenerics>,\n type: string,\n id: string | undefined,\n data: ChannelData<StreamChatGenerics>,\n ) {\n const validTypeRe = /^[\\w_-]+$/;\n const validIDRe = /^[\\w!_-]+$/;\n\n if (!validTypeRe.test(type)) {\n throw new Error(`Invalid chat type ${type}, letters, numbers and \"_-\" are allowed`);\n }\n if (typeof id === 'string' && !validIDRe.test(id)) {\n throw new Error(`Invalid chat id ${id}, letters, numbers and \"!-_\" are allowed`);\n }\n\n this._client = client;\n this.type = type;\n this.id = id;\n // used by the frontend, gets updated:\n this.data = data;\n // this._data is used for the requests...\n this._data = { ...data };\n this.cid = `${type}:${id}`;\n this.listeners = {};\n // perhaps the state variable should be private\n this.state = new ChannelState<StreamChatGenerics>(this);\n this.initialized = false;\n this.offlineMode = false;\n this.lastTypingEvent = null;\n this.isTyping = false;\n this.disconnected = false;\n }\n\n /**\n * getClient - Get the chat client for this channel. If client.disconnect() was called, this function will error\n *\n * @return {StreamChat<StreamChatGenerics>}\n */\n getClient(): StreamChat<StreamChatGenerics> {\n if (this.disconnected === true) {\n throw Error(`You can't use a channel after client.disconnect() was called`);\n }\n return this._client;\n }\n\n /**\n * getConfig - Get the config for this channel id (cid)\n *\n * @return {Record<string, unknown>}\n */\n getConfig() {\n const client = this.getClient();\n return client.configs[this.cid];\n }\n\n /**\n * sendMessage - Send a message to this channel\n *\n * @param {Message<StreamChatGenerics>} message The Message object\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n * @param {boolean} [options.skip_push] Skip sending push notifications\n * @param {boolean} [options.is_pending_message] DEPRECATED, please use `pending` instead.\n * @param {boolean} [options.pending] Make this message pending\n * @param {Record<string,string>} [options.pending_message_metadata] Metadata for the pending message\n * @param {boolean} [options.force_moderation] Apply force moderation for server-side requests\n *\n * @return {Promise<SendMessageAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendMessage(message: Message<StreamChatGenerics>, options?: SendMessageOptions) {\n return await this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(this._channelURL() + '/message', {\n message,\n ...options,\n });\n }\n\n sendFile(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/file`, uri, name, contentType, user);\n }\n\n sendImage(\n uri: string | NodeJS.ReadableStream | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/image`, uri, name, contentType, user);\n }\n\n deleteFile(url: string) {\n return this.getClient().delete<APIResponse>(`${this._channelURL()}/file`, { url });\n }\n\n deleteImage(url: string) {\n return this.getClient().delete<APIResponse>(`${this._channelURL()}/image`, { url });\n }\n\n /**\n * sendEvent - Send an event on this channel\n *\n * @param {Event<StreamChatGenerics>} event for example {type: 'message.read'}\n *\n * @return {Promise<EventAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendEvent(event: Event<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().post<EventAPIResponse<StreamChatGenerics>>(this._channelURL() + '/event', {\n event,\n });\n }\n\n /**\n * search - Query messages\n *\n * @param {MessageFilters<StreamChatGenerics> | string} query search query or object MongoDB style filters\n * @param {{client_id?: string; connection_id?: string; query?: string; message_filter_conditions?: MessageFilters<StreamChatGenerics>}} options Option object, {user_id: 'tommaso'}\n *\n * @return {Promise<SearchAPIResponse<StreamChatGenerics>>} search messages response\n */\n async search(\n query: MessageFilters<StreamChatGenerics> | string,\n options: SearchOptions<StreamChatGenerics> & {\n client_id?: string;\n connection_id?: string;\n message_filter_conditions?: MessageFilters<StreamChatGenerics>;\n query?: string;\n } = {},\n ) {\n if (options.offset && options.next) {\n throw Error(`Cannot specify offset with next`);\n }\n // Return a list of channels\n const payload: SearchPayload<StreamChatGenerics> = {\n filter_conditions: { cid: this.cid } as ChannelFilters<StreamChatGenerics>,\n ...options,\n sort: options.sort ? normalizeQuerySort<SearchMessageSortBase<StreamChatGenerics>>(options.sort) : undefined,\n };\n if (typeof query === 'string') {\n payload.query = query;\n } else if (typeof query === 'object') {\n payload.message_filter_conditions = query;\n } else {\n throw Error(`Invalid type ${typeof query} for query parameter`);\n }\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n return await this.getClient().get<SearchAPIResponse<StreamChatGenerics>>(this.getClient().baseURL + '/search', {\n payload,\n });\n }\n\n /**\n * queryMembers - Query Members\n *\n * @param {MemberFilters<StreamChatGenerics>} filterConditions object MongoDB style filters\n * @param {MemberSort<StreamChatGenerics>} [sort] Sort options, for instance [{created_at: -1}].\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{name: -1}, {created_at: 1}]\n * @param {{ limit?: number; offset?: number }} [options] Option object, {limit: 10, offset:10}\n *\n * @return {Promise<ChannelMemberAPIResponse<StreamChatGenerics>>} Query Members response\n */\n async queryMembers(\n filterConditions: MemberFilters<StreamChatGenerics>,\n sort: MemberSort<StreamChatGenerics> = [],\n options: QueryMembersOptions = {},\n ) {\n let id: string | undefined;\n const type = this.type;\n let members: string[] | ChannelMemberResponse<StreamChatGenerics>[] | undefined;\n if (this.id) {\n id = this.id;\n } else if (this.data?.members && Array.isArray(this.data.members)) {\n members = this.data.members;\n }\n // Return a list of members\n return await this.getClient().get<ChannelMemberAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + '/members',\n {\n payload: {\n type,\n id,\n members,\n sort: normalizeQuerySort(sort),\n filter_conditions: filterConditions,\n ...options,\n },\n },\n );\n }\n\n /**\n * partialUpdateMember - Partial update a member\n *\n * @param {string} user_id member user id\n * @param {PartialUpdateMember<StreamChatGenerics>} updates\n *\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} Updated member\n */\n async partialUpdateMember(user_id: string, updates: PartialUpdateMember<StreamChatGenerics>) {\n if (!user_id) {\n throw Error('Please specify the user id');\n }\n\n return await this.getClient().patch<PartialUpdateMemberAPIResponse<StreamChatGenerics>>(\n this._channelURL() + `/member/${encodeURIComponent(user_id)}`,\n updates,\n );\n }\n\n /**\n * sendReaction - Send a reaction about a message\n *\n * @param {string} messageID the message id\n * @param {Reaction<StreamChatGenerics>} reaction the reaction object for instance {type: 'love'}\n * @param {{ enforce_unique?: boolean, skip_push?: boolean }} [options] Option object, {enforce_unique: true, skip_push: true} to override any existing reaction or skip sending push notifications\n *\n * @return {Promise<ReactionAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendReaction(\n messageID: string,\n reaction: Reaction<StreamChatGenerics>,\n options?: { enforce_unique?: boolean; skip_push?: boolean },\n ) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n if (!reaction || Object.keys(reaction).length === 0) {\n throw Error(`Reaction object is missing`);\n }\n return await this.getClient().post<ReactionAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/reaction`,\n {\n reaction,\n ...options,\n },\n );\n }\n\n /**\n * deleteReaction - Delete a reaction by user and type\n *\n * @param {string} messageID the id of the message from which te remove the reaction\n * @param {string} reactionType the type of reaction that should be removed\n * @param {string} [user_id] the id of the user (used only for server side request) default null\n *\n * @return {Promise<ReactionAPIResponse<StreamChatGenerics>>} The Server Response\n */\n deleteReaction(messageID: string, reactionType: string, user_id?: string) {\n this._checkInitialized();\n if (!reactionType || !messageID) {\n throw Error('Deleting a reaction requires specifying both the message and reaction type');\n }\n\n const url =\n this.getClient().baseURL +\n `/messages/${encodeURIComponent(messageID)}/reaction/${encodeURIComponent(reactionType)}`;\n //provided when server side request\n if (user_id) {\n return this.getClient().delete<ReactionAPIResponse<StreamChatGenerics>>(url, { user_id });\n }\n\n return this.getClient().delete<ReactionAPIResponse<StreamChatGenerics>>(url, {});\n }\n\n /**\n * update - Edit the channel's custom properties\n *\n * @param {ChannelData<StreamChatGenerics>} channelData The object to update the custom properties of this channel with\n * @param {Message<StreamChatGenerics>} [updateMessage] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async update(\n channelData: Partial<ChannelData<StreamChatGenerics>> | Partial<ChannelResponse<StreamChatGenerics>> = {},\n updateMessage?: Message<StreamChatGenerics>,\n options?: ChannelUpdateOptions,\n ) {\n // Strip out reserved names that will result in API errors.\n const reserved = [\n 'config',\n 'cid',\n 'created_by',\n 'id',\n 'member_count',\n 'type',\n 'created_at',\n 'updated_at',\n 'last_message_at',\n 'own_capabilities',\n ];\n reserved.forEach((key) => {\n delete channelData[key];\n });\n\n return await this._update({\n message: updateMessage,\n data: channelData,\n ...options,\n });\n }\n\n /**\n * updatePartial - partial update channel properties\n *\n * @param {PartialUpdateChannel<StreamChatGenerics>} partial update request\n *\n * @return {Promise<PartialUpdateChannelAPIResponse<StreamChatGenerics>>}\n */\n async updatePartial(update: PartialUpdateChannel<StreamChatGenerics>) {\n const data = await this.getClient().patch<PartialUpdateChannelAPIResponse<StreamChatGenerics>>(\n this._channelURL(),\n update,\n );\n\n const areCapabilitiesChanged =\n [...(data.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = data.channel;\n // If the capabiltities are changed, we trigger the `capabilities.changed` event.\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: data.channel.own_capabilities,\n });\n }\n return data;\n }\n\n /**\n * enableSlowMode - enable slow mode\n *\n * @param {number} coolDownInterval the cooldown interval in seconds\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async enableSlowMode(coolDownInterval: number) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n cooldown: coolDownInterval,\n });\n this.data = data.channel;\n return data;\n }\n\n /**\n * disableSlowMode - disable slow mode\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async disableSlowMode() {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n cooldown: 0,\n });\n this.data = data.channel;\n return data;\n }\n\n /**\n * delete - Delete the channel. Messages are permanently removed.\n *\n * @param {boolean} [options.hard_delete] Defines if the channel is hard deleted or not\n *\n * @return {Promise<DeleteChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async delete(options: { hard_delete?: boolean } = {}) {\n return await this.getClient().delete<DeleteChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n ...options,\n });\n }\n\n /**\n * truncate - Removes all messages from the channel\n * @param {TruncateOptions<StreamChatGenerics>} [options] Defines truncation options\n * @return {Promise<TruncateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async truncate(options: TruncateOptions<StreamChatGenerics> = {}) {\n return await this.getClient().post<TruncateChannelAPIResponse<StreamChatGenerics>>(\n this._channelURL() + '/truncate',\n options,\n );\n }\n\n /**\n * acceptInvite - accept invitation to the channel\n *\n * @param {InviteOptions<StreamChatGenerics>} [options] The object to update the custom properties of this channel with\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async acceptInvite(options: InviteOptions<StreamChatGenerics> = {}) {\n return await this._update({ accept_invite: true, ...options });\n }\n\n /**\n * rejectInvite - reject invitation to the channel\n *\n * @param {InviteOptions<StreamChatGenerics>} [options] The object to update the custom properties of this channel with\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async rejectInvite(options: InviteOptions<StreamChatGenerics> = {}) {\n return await this._update({ reject_invite: true, ...options });\n }\n\n /**\n * addMembers - add members to the channel\n *\n * @param {string[] | Array<NewMemberPayload<StreamChatGenerics>>} members An array of members to add to the channel\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async addMembers(\n members: string[] | Array<NewMemberPayload<StreamChatGenerics>>,\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ add_members: members, message, ...options });\n }\n\n /**\n * addModerators - add moderators to the channel\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async addModerators(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ add_moderators: members, message, ...options });\n }\n\n /**\n * assignRoles - sets member roles in a channel\n *\n * @param {{channel_role: Role, user_id: string}[]} roles List of role assignments\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async assignRoles(\n roles: { channel_role: Role; user_id: string }[],\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ assign_roles: roles, message, ...options });\n }\n\n /**\n * inviteMembers - invite members to the channel\n *\n * @param {string[] | Array<NewMemberPayload<StreamChatGenerics>>} members An array of members to invite to the channel\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async inviteMembers(\n members: string[] | Array<NewMemberPayload<StreamChatGenerics>>,\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ invites: members, message, ...options });\n }\n\n /**\n * removeMembers - remove members from channel\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async removeMembers(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ remove_members: members, message, ...options });\n }\n\n /**\n * demoteModerators - remove moderator role from channel members\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async demoteModerators(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ demote_moderators: members, message, ...options });\n }\n\n /**\n * _update - executes channel update request\n * @param payload Object Update Channel payload\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n * TODO: introduce new type instead of Object in the next major update\n */\n async _update(payload: Object) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), payload);\n this.data = data.channel;\n return data;\n }\n\n /**\n * mute - mutes the current channel\n * @param {{ user_id?: string, expiration?: string }} opts expiration in minutes or user_id\n * @return {Promise<MuteChannelAPIResponse<StreamChatGenerics>>} The server response\n *\n * example with expiration:\n * await channel.mute({expiration: moment.duration(2, 'weeks')});\n *\n * example server side:\n * await channel.mute({user_id: userId});\n *\n */\n async mute(opts: { expiration?: number; user_id?: string } = {}) {\n return await this.getClient().post<MuteChannelAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + '/moderation/mute/channel',\n { channel_cid: this.cid, ...opts },\n );\n }\n\n /**\n * unmute - mutes the current channel\n * @param {{ user_id?: string}} opts user_id\n * @return {Promise<APIResponse>} The server response\n *\n * example server side:\n * await channel.unmute({user_id: userId});\n */\n async unmute(opts: { user_id?: string } = {}) {\n return await this.getClient().post<APIResponse>(this.getClient().baseURL + '/moderation/unmute/channel', {\n channel_cid: this.cid,\n ...opts,\n });\n }\n\n /**\n * archive - archives the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.archives();\n *\n * example server side:\n * await channel.archive({user_id: userId});\n *\n */\n async archive(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw Error('A user_id is required for archiving a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { archived: true } });\n return resp.channel_member;\n }\n\n /**\n * unarchive - unarchives the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.unarchive();\n *\n * example server side:\n * await channel.unarchive({user_id: userId});\n *\n */\n async unarchive(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw Error('A user_id is required for unarchiving a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { archived: false } });\n return resp.channel_member;\n }\n\n /**\n * pin - pins the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.pin();\n *\n * example server side:\n * await channel.pin({user_id: userId});\n *\n */\n async pin(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw new Error('A user_id is required for pinning a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { pinned: true } });\n return resp.channel_member;\n }\n\n /**\n * unpin - unpins the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.unpin();\n *\n * example server side:\n * await channel.unpin({user_id: userId});\n *\n */\n async unpin(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw new Error('A user_id is required for unpinning a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { pinned: false } });\n return resp.channel_member;\n }\n\n /**\n * muteStatus - returns the mute status for the current channel\n * @return {{ muted: boolean; createdAt: Date | null; expiresAt: Date | null }} { muted: true | false, createdAt: Date | null, expiresAt: Date | null}\n */\n muteStatus(): {\n createdAt: Date | null;\n expiresAt: Date | null;\n muted: boolean;\n } {\n this._checkInitialized();\n return this.getClient()._muteStatus(this.cid);\n }\n\n sendAction(messageID: string, formData: Record<string, string>) {\n this._checkInitialized();\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/action`,\n {\n message_id: messageID,\n form_data: formData,\n id: this.id,\n type: this.type,\n },\n );\n }\n\n /**\n * keystroke - First of the typing.start and typing.stop events based on the users keystrokes.\n * Call this on every keystroke\n * @see {@link https://getstream.io/chat/docs/typing_indicators/?language=js|Docs}\n * @param {string} [parent_id] set this field to `message.id` to indicate that typing event is happening in a thread\n */\n async keystroke(parent_id?: string, options?: { user_id: string }) {\n if (!this._isTypingIndicatorsEnabled()) {\n return;\n }\n const now = new Date();\n const diff = this.lastTypingEvent && now.getTime() - this.lastTypingEvent.getTime();\n this.lastKeyStroke = now;\n this.isTyping = true;\n // send a typing.start every 2 seconds\n if (diff === null || diff > 2000) {\n this.lastTypingEvent = new Date();\n await this.sendEvent({\n type: 'typing.start',\n parent_id,\n ...(options || {}),\n } as Event<StreamChatGenerics>);\n }\n }\n\n /**\n * stopTyping - Sets last typing to null and sends the typing.stop event\n * @see {@link https://getstream.io/chat/docs/typing_indicators/?language=js|Docs}\n * @param {string} [parent_id] set this field to `message.id` to indicate that typing event is happening in a thread\n */\n async stopTyping(parent_id?: string, options?: { user_id: string }) {\n if (!this._isTypingIndicatorsEnabled()) {\n return;\n }\n this.lastTypingEvent = null;\n this.isTyping = false;\n await this.sendEvent({\n type: 'typing.stop',\n parent_id,\n ...(options || {}),\n } as Event<StreamChatGenerics>);\n }\n\n _isTypingIndicatorsEnabled(): boolean {\n if (!this.getConfig()?.typing_events) {\n return false;\n }\n return this.getClient().user?.privacy_settings?.typing_indicators?.enabled ?? true;\n }\n\n /**\n * lastMessage - return the last message, takes into account that last few messages might not be perfectly sorted\n *\n * @return {ReturnType<ChannelState<StreamChatGenerics>['formatMessage']> | undefined} Description\n */\n lastMessage(): FormatMessageResponse<StreamChatGenerics> | undefined {\n // get last 5 messages, sort, return the latest\n // get a slice of the last 5\n let min = this.state.latestMessages.length - 5;\n if (min < 0) {\n min = 0;\n }\n const max = this.state.latestMessages.length + 1;\n const messageSlice = this.state.latestMessages.slice(min, max);\n\n // sort by pk desc\n messageSlice.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());\n\n return messageSlice[0];\n }\n\n /**\n * markRead - Send the mark read event for this user, only works if the `read_events` setting is enabled\n *\n * @param {MarkReadOptions<StreamChatGenerics>} data\n * @return {Promise<EventAPIResponse<StreamChatGenerics> | null>} Description\n */\n async markRead(data: MarkReadOptions<StreamChatGenerics> = {}) {\n this._checkInitialized();\n\n if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {\n return Promise.resolve(null);\n }\n\n return await this.getClient().post<EventAPIResponse<StreamChatGenerics>>(this._channelURL() + '/read', {\n ...data,\n });\n }\n\n /**\n * markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is enabled\n *\n * @param {MarkUnreadOptions<StreamChatGenerics>} data\n * @return {APIResponse} An API response\n */\n async markUnread(data: MarkUnreadOptions<StreamChatGenerics>) {\n this._checkInitialized();\n\n if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {\n return Promise.resolve(null);\n }\n\n return await this.getClient().post<APIResponse>(this._channelURL() + '/unread', {\n ...data,\n });\n }\n\n /**\n * clean - Cleans the channel state and fires stop typing if needed\n */\n clean() {\n if (this.lastKeyStroke) {\n const now = new Date();\n const diff = now.getTime() - this.lastKeyStroke.getTime();\n if (diff > 1000 && this.isTyping) {\n logChatPromiseExecution(this.stopTyping(), 'stop typing event');\n }\n }\n\n this.state.clean();\n }\n\n /**\n * watch - Loads the initial channel state and watches for changes\n *\n * @param {ChannelQueryOptions<StreamChatGenerics>} options additional options for the query endpoint\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async watch(options?: ChannelQueryOptions<StreamChatGenerics>) {\n const defaultOptions = {\n state: true,\n watch: true,\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n if (!this.getClient()._hasConnectionID()) {\n defaultOptions.watch = false;\n }\n\n const combined = { ...defaultOptions, ...options };\n const state = await this.query(combined, 'latest');\n this.initialized = true;\n this.data = state.channel;\n\n this._client.logger('info', `channel:watch() - started watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n return state;\n }\n\n /**\n * stopWatching - Stops watching the channel\n *\n * @return {Promise<APIResponse>} The server response\n */\n async stopWatching() {\n const response = await this.getClient().post<APIResponse>(this._channelURL() + '/stop-watching', {});\n\n this._client.logger('info', `channel:watch() - stopped watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n\n return response;\n }\n\n /**\n * getReplies - List the message replies for a parent message.\n *\n * The recommended way of working with threads is to use the Thread class.\n *\n * @param {string} parent_id The message parent id, ie the top of the thread\n * @param {MessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}\n *\n * @return {Promise<GetRepliesAPIResponse<StreamChatGenerics>>} A response with a list of messages\n */\n async getReplies(\n parent_id: string,\n options: MessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string },\n sort?: { created_at: AscDesc }[],\n ) {\n const normalizedSort = sort ? normalizeQuerySort(sort) : undefined;\n const data = await this.getClient().get<GetRepliesAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(parent_id)}/replies`,\n {\n sort: normalizedSort,\n ...options,\n },\n );\n\n // add any messages to our thread state\n if (data.messages) {\n this.state.addMessagesSorted(data.messages);\n }\n\n return data;\n }\n\n /**\n * getPinnedMessages - List list pinned messages of the channel\n *\n * @param {PinnedMessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}\n * @param {PinnedMessagesSort} sort defines sorting direction of pinned messages\n *\n * @return {Promise<GetRepliesAPIResponse<StreamChatGenerics>>} A response with a list of messages\n */\n async getPinnedMessages(\n options: PinnedMessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string },\n sort: PinnedMessagesSort = [],\n ) {\n return await this.getClient().get<GetRepliesAPIResponse<StreamChatGenerics>>(\n this._channelURL() + '/pinned_messages',\n {\n payload: {\n ...options,\n sort: normalizeQuerySort(sort),\n },\n },\n );\n }\n\n /**\n * getReactions - List the reactions, supports pagination\n *\n * @param {string} message_id The message id\n * @param {{ limit?: number; offset?: number }} options The pagination options\n *\n * @return {Promise<GetReactionsAPIResponse<StreamChatGenerics>>} Server response\n */\n getReactions(message_id: string, options: { limit?: number; offset?: number }) {\n return this.getClient().get<GetReactionsAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(message_id)}/reactions`,\n {\n ...options,\n },\n );\n }\n\n /**\n * getMessagesById - Retrieves a list of messages by ID\n *\n * @param {string[]} messageIds The ids of the messages to retrieve from this channel\n *\n * @return {Promise<GetMultipleMessagesAPIResponse<StreamChatGenerics>>} Server response\n */\n getMessagesById(messageIds: string[]) {\n return this.getClient().get<GetMultipleMessagesAPIResponse<StreamChatGenerics>>(this._channelURL() + '/messages', {\n ids: messageIds.join(','),\n });\n }\n\n /**\n * lastRead - returns the last time the user marked the channel as read if the user never marked the channel as read, this will return null\n * @return {Date | null | undefined}\n */\n lastRead() {\n const { userID } = this.getClient();\n if (userID) {\n return this.state.read[userID] ? this.state.read[userID].last_read : null;\n }\n }\n\n _countMessageAsUnread(message: FormatMessageResponse<StreamChatGenerics> | MessageResponse<StreamChatGenerics>) {\n if (message.shadowed) return false;\n if (message.silent) return false;\n if (message.parent_id && !message.show_in_channel) return false;\n if (message.user?.id === this.getClient().userID) return false;\n if (message.user?.id && this.getClient().userMuteStatus(message.user.id)) return false;\n\n // Return false if channel doesn't allow read events.\n if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes('read-events'))\n return false;\n\n // FIXME: see #1265, adjust and count new messages even when the channel is muted\n if (this.muteStatus().muted) return false;\n\n return true;\n }\n\n /**\n * countUnread - Count of unread messages\n *\n * @param {Date | null} [lastRead] lastRead the time that the user read a message, defaults to current user's read state\n *\n * @return {number} Unread count\n */\n countUnread(lastRead?: Date | null) {\n if (!lastRead) return this.state.unreadCount;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (message.created_at > lastRead && this._countMessageAsUnread(message)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * countUnreadMentions - Count the number of unread messages mentioning the current user\n *\n * @return {number} Unread mentions count\n */\n countUnreadMentions() {\n const lastRead = this.lastRead();\n const userID = this.getClient().userID;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (\n this._countMessageAsUnread(message) &&\n (!lastRead || message.created_at > lastRead) &&\n message.mentioned_users?.some((user) => user.id === userID)\n ) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * create - Creates a new channel\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} The Server Response\n *\n */\n create = async (options?: ChannelQueryOptions<StreamChatGenerics>) => {\n const defaultOptions = {\n ...options,\n watch: false,\n state: false,\n presence: false,\n };\n return await this.query(defaultOptions, 'latest');\n };\n\n /**\n * query - Query the API, get messages, members or other channel fields\n *\n * @param {ChannelQueryOptions<StreamChatGenerics>} options The query options\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist It's possible to load disjunct sets of a channel's messages into state, use `current` to load the initial channel state or if you want to extend the currently displayed messages, use `latest` if you want to load/extend the latest messages, `new` is used for loading a specific message and it's surroundings\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} Returns a query response\n */\n async query(\n options?: ChannelQueryOptions<StreamChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n let queryURL = `${this.getClient().baseURL}/channels/${encodeURIComponent(this.type)}`;\n if (this.id) {\n queryURL += `/${encodeURIComponent(this.id)}`;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<StreamChatGenerics>>(queryURL + '/query', {\n data: this._data,\n state: true,\n ...options,\n });\n\n // update the channel id if it was missing\n if (!this.id) {\n this.id = state.channel.id;\n this.cid = state.channel.cid;\n // set the channel as active...\n\n const membersStr = state.members\n .map((member) => member.user_id || member.user?.id)\n .sort()\n .join(',');\n const tempChannelCid = `${this.type}:!members-${membersStr}`;\n\n if (tempChannelCid in this.getClient().activeChannels) {\n // This gets set in `client.channel()` function, when channel is created\n // using members, not id.\n delete this.getClient().activeChannels[tempChannelCid];\n }\n\n if (!(this.cid in this.getClient().activeChannels)) {\n this.getClient().activeChannels[this.cid] = this;\n }\n }\n\n this.getClient()._addChannelConfig(state.channel);\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n messageSet.pagination = {\n ...messageSet.pagination,\n ...messageSetPagination({\n parentSet: messageSet,\n messagePaginationOptions: options?.messages,\n requestedPageSize: options?.messages?.limit ?? DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE,\n returnedPage: state.messages,\n logger: this.getClient().logger,\n }),\n };\n\n this.getClient().polls.hydratePollCache(messageSet.messages, true);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n this.getClient().dispatchEvent({\n type: 'channels.queried',\n queriedChannels: {\n channels: [state],\n isLatestMessageSet: messageSet.isLatest,\n },\n });\n\n return state;\n }\n\n /**\n * banUser - Bans a user from a channel\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} options\n * @returns {Promise<APIResponse>}\n */\n async banUser(targetUserID: string, options: BanUserOptions<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().banUser(targetUserID, {\n ...options,\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * hides the channel from queryChannels for the user until a message is added\n * If clearHistory is set to true - all messages will be removed for the user\n *\n * @param {string | null} userId\n * @param {boolean} clearHistory\n * @returns {Promise<APIResponse>}\n */\n async hide(userId: string | null = null, clearHistory = false) {\n this._checkInitialized();\n\n return await this.getClient().post<APIResponse>(`${this._channelURL()}/hide`, {\n user_id: userId,\n clear_history: clearHistory,\n });\n }\n\n /**\n * removes the hidden status for a channel\n *\n * @param {string | null} userId\n * @returns {Promise<APIResponse>}\n */\n async show(userId: string | null = null) {\n this._checkInitialized();\n return await this.getClient().post<APIResponse>(`${this._channelURL()}/show`, {\n user_id: userId,\n });\n }\n\n /**\n * unbanUser - Removes the bans for a user on a channel\n *\n * @param {string} targetUserID\n * @returns {Promise<APIResponse>}\n */\n async unbanUser(targetUserID: string) {\n this._checkInitialized();\n return await this.getClient().unbanUser(targetUserID, {\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * shadowBan - Shadow bans a user from a channel\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} options\n * @returns {Promise<APIResponse>}\n */\n async shadowBan(targetUserID: string, options: BanUserOptions<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().shadowBan(targetUserID, {\n ...options,\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * removeShadowBan - Removes the shadow ban for a user on a channel\n *\n * @param {string} targetUserID\n * @returns {Promise<APIResponse>}\n */\n async removeShadowBan(targetUserID: string) {\n this._checkInitialized();\n return await this.getClient().removeShadowBan(targetUserID, {\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * createCall - creates a call for the current channel\n *\n * @param {CreateCallOptions} options\n * @returns {Promise<CreateCallResponse>}\n */\n async createCall(options: CreateCallOptions) {\n return await this.getClient().post<CreateCallResponse>(this._channelURL() + '/call', options);\n }\n\n /**\n * Cast or cancel one or more votes on a poll\n * @param pollId string The poll id\n * @param votes PollVoteData[] The votes that will be casted (or canceled in case of an empty array)\n * @returns {APIResponse & PollVoteResponse} The poll votes\n */\n async vote(messageId: string, pollId: string, vote: PollVoteData) {\n return await this.getClient().castPollVote(messageId, pollId, vote);\n }\n\n async removeVote(messageId: string, pollId: string, voteId: string) {\n return await this.getClient().removePollVote(messageId, pollId, voteId);\n }\n\n /**\n * on - Listen to events on this channel.\n *\n * channel.on('message.new', event => {console.log(\"my new message\", event, channel.state.messages)})\n * or\n * channel.on(event => {console.log(event.type)})\n *\n * @param {EventHandler<StreamChatGenerics> | EventTypes} callbackOrString The event type to listen for (optional)\n * @param {EventHandler<StreamChatGenerics>} [callbackOrNothing] The callback to call\n */\n on(eventType: EventTypes, callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<StreamChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this._client.logger('info', `Attaching listener for ${key} event on channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key].push(callback);\n\n return {\n unsubscribe: () => {\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n /**\n * off - Remove the event handler\n *\n */\n off(eventType: EventTypes, callback: EventHandler<StreamChatGenerics>): void;\n off(callback: EventHandler<StreamChatGenerics>): void;\n off(\n callbackOrString: EventHandler<StreamChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): void {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _handleChannelEvent(event: Event<StreamChatGenerics>) {\n const channel = this;\n this._client.logger(\n 'info',\n `channel:_handleChannelEvent - Received event of type { ${event.type} } on ${this.cid}`,\n {\n tags: ['event', 'channel'],\n channel: this,\n },\n );\n\n const channelState = channel.state;\n switch (event.type) {\n case 'typing.start':\n if (event.user?.id) {\n channelState.typing[event.user.id] = event;\n }\n break;\n case 'typing.stop':\n if (event.user?.id) {\n delete channelState.typing[event.user.id];\n }\n break;\n case 'message.read':\n if (event.user?.id && event.created_at) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at),\n last_read_message_id: event.last_read_message_id,\n user: event.user,\n unread_messages: 0,\n };\n\n if (event.user?.id === this.getClient().user?.id) {\n channelState.unreadCount = 0;\n }\n }\n break;\n case 'user.watching.start':\n case 'user.updated':\n if (event.user?.id) {\n channelState.watchers[event.user.id] = event.user;\n }\n break;\n case 'user.watching.stop':\n if (event.user?.id) {\n delete channelState.watchers[event.user.id];\n }\n break;\n case 'message.deleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n if (event.hard_delete) channelState.removeMessage(event.message);\n else channelState.addMessageSorted(event.message, false, false);\n\n channelState.removeQuotedMessageReferences(event.message);\n\n if (event.message.pinned) {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.new':\n if (event.message) {\n /* if message belongs to current user, always assume timestamp is changed to filter it out and add again to avoid duplication */\n const ownMessage = event.user?.id === this.getClient().user?.id;\n const isThreadMessage = event.message.parent_id && !event.message.show_in_channel;\n\n if (this.state.isUpToDate || isThreadMessage) {\n channelState.addMessageSorted(event.message, ownMessage);\n }\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n\n // do not increase the unread count - the back-end does not increase the count neither in the following cases:\n // 1. the message is mine\n // 2. the message is a thread reply from any user\n const preventUnreadCountUpdate = ownMessage || isThreadMessage;\n if (preventUnreadCountUpdate) break;\n\n if (event.user?.id) {\n for (const userId in channelState.read) {\n if (userId === event.user.id) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at as string),\n user: event.user,\n unread_messages: 0,\n };\n } else {\n channelState.read[userId].unread_messages += 1;\n }\n }\n }\n\n if (this._countMessageAsUnread(event.message)) {\n channelState.unreadCount = channelState.unreadCount + 1;\n }\n }\n break;\n case 'message.updated':\n case 'message.undeleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n channelState.addMessageSorted(event.message, false, false);\n channelState._updateQuotedMessageReferences({ message: event.message });\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n } else {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'channel.truncated':\n if (event.channel?.truncated_at) {\n const truncatedAt = +new Date(event.channel.truncated_at);\n\n channelState.messageSets.forEach((messageSet, messageSetIndex) => {\n messageSet.messages.forEach(({ created_at: createdAt, id }) => {\n if (truncatedAt > +createdAt) channelState.removeMessage({ id, messageSetIndex });\n });\n });\n\n channelState.pinnedMessages.forEach(({ id, created_at: createdAt }) => {\n if (truncatedAt > +createdAt)\n channelState.removePinnedMessage({ id } as MessageResponse<StreamChatGenerics>);\n });\n } else {\n channelState.clearMessages();\n }\n\n channelState.unreadCount = 0;\n // system messages don't increment unread counts\n if (event.message) {\n channelState.addMessageSorted(event.message);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n }\n break;\n case 'member.added':\n case 'member.updated':\n if (event.member?.user_id) {\n channelState.members = {\n ...channelState.members,\n [event.member.user_id]: event.member,\n };\n }\n break;\n case 'member.removed':\n if (event.user?.id) {\n const newMembers = {\n ...channelState.members,\n };\n\n delete newMembers[event.user.id];\n\n channelState.members = newMembers;\n }\n break;\n case 'notification.mark_unread': {\n const ownMessage = event.user?.id === this.getClient().user?.id;\n if (!(ownMessage && event.user)) break;\n\n const unreadCount = event.unread_messages ?? 0;\n\n channelState.read[event.user.id] = {\n first_unread_message_id: event.first_unread_message_id,\n last_read: new Date(event.last_read_at as string),\n last_read_message_id: event.last_read_message_id,\n user: event.user,\n unread_messages: unreadCount,\n };\n\n channelState.unreadCount = unreadCount;\n break;\n }\n case 'channel.updated':\n if (event.channel) {\n const isFrozenChanged = event.channel?.frozen !== undefined && event.channel.frozen !== channel.data?.frozen;\n if (isFrozenChanged) {\n this.query({ state: false, messages: { limit: 0 }, watchers: { limit: 0 } });\n }\n channel.data = {\n ...event.channel,\n hidden: event.channel?.hidden ?? channel.data?.hidden,\n own_capabilities: event.channel?.own_capabilities ?? channel.data?.own_capabilities,\n };\n }\n break;\n case 'reaction.new':\n if (event.message && event.reaction) {\n event.message = channelState.addReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.deleted':\n if (event.reaction) {\n event.message = channelState.removeReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.updated':\n if (event.reaction) {\n // assuming reaction.updated is only called if enforce_unique is true\n event.message = channelState.addReaction(event.reaction, event.message, true);\n }\n break;\n case 'channel.hidden':\n channel.data = { ...channel.data, hidden: true };\n if (event.clear_history) {\n channelState.clearMessages();\n }\n break;\n case 'channel.visible':\n channel.data = { ...channel.data, hidden: false };\n break;\n case 'user.banned':\n if (!event.user?.id) break;\n channelState.members[event.user.id] = {\n ...(channelState.members[event.user.id] || {}),\n shadow_banned: !!event.shadow,\n banned: !event.shadow,\n user: { ...(channelState.members[event.user.id]?.user || {}), ...event.user },\n };\n break;\n case 'user.unbanned':\n if (!event.user?.id) break;\n channelState.members[event.user.id] = {\n ...(channelState.members[event.user.id] || {}),\n shadow_banned: false,\n banned: false,\n user: { ...(channelState.members[event.user.id]?.user || {}), ...event.user },\n };\n break;\n default:\n }\n\n // any event can send over the online count\n if (event.watcher_count !== undefined) {\n channel.state.watcher_count = event.watcher_count;\n }\n }\n\n _callChannelListeners = (event: Event<StreamChatGenerics>) => {\n const channel = this;\n // gather and call the listeners\n const listeners = [];\n if (channel.listeners.all) {\n listeners.push(...channel.listeners.all);\n }\n if (channel.listeners[event.type]) {\n listeners.push(...channel.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n if (typeof listener !== 'string') {\n listener(event);\n }\n }\n };\n\n /**\n * _channelURL - Returns the channel url\n *\n * @return {string} The channel url\n */\n _channelURL = () => {\n if (!this.id) {\n throw new Error('channel id is not defined');\n }\n return `${this.getClient().baseURL}/channels/${encodeURIComponent(this.type)}/${encodeURIComponent(this.id)}`;\n };\n\n _checkInitialized() {\n if (!this.initialized && !this.offlineMode && !this.getClient()._isUsingServerAuth()) {\n throw Error(\n `Channel ${this.cid} hasn't been initialized yet. Make sure to call .watch() and wait for it to resolve`,\n );\n }\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _initializeState(\n state: ChannelAPIResponse<StreamChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n const { state: clientState, user, userID } = this.getClient();\n\n // add the Users\n if (state.members) {\n for (const member of state.members) {\n if (member.user) {\n clientState.updateUserReference(member.user, this.cid);\n }\n }\n }\n\n this.state.membership = state.membership || {};\n\n const messages = state.messages || [];\n if (!this.state.messages) {\n this.state.initMessages();\n }\n const { messageSet } = this.state.addMessagesSorted(messages, false, true, true, messageSetToAddToIfDoesNotExist);\n\n if (!this.state.pinnedMessages) {\n this.state.pinnedMessages = [];\n }\n this.state.addPinnedMessages(state.pinned_messages || []);\n if (state.pending_messages) {\n this.state.pending_messages = state.pending_messages;\n }\n if (state.watcher_count !== undefined) {\n this.state.watcher_count = state.watcher_count;\n }\n // convert the arrays into objects for easier syncing...\n if (state.watchers) {\n for (const watcher of state.watchers) {\n if (watcher) {\n clientState.updateUserReference(watcher, this.cid);\n this.state.watchers[watcher.id] = watcher;\n }\n }\n }\n\n // initialize read state to last message or current time if the channel is empty\n // if the user is a member, this value will be overwritten later on otherwise this ensures\n // that everything up to this point is not marked as unread\n if (userID != null) {\n const last_read = this.state.last_message_at || new Date();\n if (user) {\n this.state.read[user.id] = {\n user,\n last_read,\n unread_messages: 0,\n };\n }\n }\n\n // apply read state if part of the state\n if (state.read) {\n for (const read of state.read) {\n this.state.read[read.user.id] = {\n last_read: new Date(read.last_read),\n last_read_message_id: read.last_read_message_id,\n unread_messages: read.unread_messages ?? 0,\n user: read.user,\n };\n\n if (read.user.id === user?.id) {\n this.state.unreadCount = this.state.read[read.user.id].unread_messages;\n }\n }\n }\n\n if (state.members) {\n this._hydrateMembers(state.members);\n }\n\n return {\n messageSet,\n };\n }\n\n _extendEventWithOwnReactions(event: Event<StreamChatGenerics>) {\n if (!event.message) {\n return;\n }\n const message = this.state.findMessage(event.message.id, event.message.parent_id);\n if (message) {\n event.message.own_reactions = message.own_reactions;\n }\n }\n\n _hydrateMembers(members: ChannelMemberResponse<StreamChatGenerics>[]) {\n this.state.members = members.reduce((acc, member) => {\n if (member.user) {\n acc[member.user.id] = member;\n }\n return acc;\n }, {} as ChannelState<StreamChatGenerics>['members']);\n }\n\n _disconnect() {\n this._client.logger('info', `channel:disconnect() - Disconnecting the channel ${this.cid}`, {\n tags: ['connection', 'channel'],\n channel: this,\n });\n\n this.disconnected = true;\n this.state.setIsUpToDate(false);\n }\n}\n","import { UserResponse, ExtendableGenerics, DefaultGenerics } from './types';\n\n/**\n * ClientState - A container class for the client state.\n */\nexport class ClientState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n users: {\n [key: string]: UserResponse<StreamChatGenerics>;\n };\n userChannelReferences: { [key: string]: { [key: string]: boolean } };\n constructor() {\n // show the status for a certain user...\n // ie online, offline etc\n this.users = {};\n // store which channels contain references to the specified user...\n this.userChannelReferences = {};\n }\n\n updateUsers(users: UserResponse<StreamChatGenerics>[]) {\n for (const user of users) {\n this.updateUser(user);\n }\n }\n\n updateUser(user?: UserResponse<StreamChatGenerics>) {\n if (user != null) {\n this.users[user.id] = user;\n }\n }\n\n updateUserReference(user: UserResponse<StreamChatGenerics>, channelID: string) {\n if (user == null) {\n return;\n }\n this.updateUser(user);\n if (!this.userChannelReferences[user.id]) {\n this.userChannelReferences[user.id] = {};\n }\n this.userChannelReferences[user.id][channelID] = true;\n }\n\n deleteAllChannelReference(channelID: string) {\n for (const userID in this.userChannelReferences) {\n delete this.userChannelReferences[userID][channelID];\n }\n }\n}\n","// https://github.com/maxogden/websocket-stream/blob/48dc3ddf943e5ada668c31ccd94e9186f02fafbd/ws-fallback.js\n\nvar ws = null\n\nif (typeof WebSocket !== 'undefined') {\n ws = WebSocket\n} else if (typeof MozWebSocket !== 'undefined') {\n ws = MozWebSocket\n} else if (typeof global !== 'undefined') {\n ws = global.WebSocket || global.MozWebSocket\n} else if (typeof window !== 'undefined') {\n ws = window.WebSocket || window.MozWebSocket\n} else if (typeof self !== 'undefined') {\n ws = self.WebSocket || self.MozWebSocket\n}\n\nmodule.exports = ws\n","import axios from 'axios';\nimport { StableWSConnection } from './connection';\nimport { randomId, sleep } from './utils';\n\nexport type InsightTypes = 'ws_fatal' | 'ws_success_after_failure' | 'http_hi_failed';\nexport class InsightMetrics {\n connectionStartTimestamp: number | null;\n wsConsecutiveFailures: number;\n wsTotalFailures: number;\n instanceClientId: string;\n\n constructor() {\n this.connectionStartTimestamp = null;\n this.wsTotalFailures = 0;\n this.wsConsecutiveFailures = 0;\n this.instanceClientId = randomId();\n }\n}\n\n/**\n * postInsights is not supposed to be used by end users directly within chat application, and thus is kept isolated\n * from all the client/connection code/logic.\n *\n * @param insightType\n * @param insights\n */\nexport const postInsights = async (insightType: InsightTypes, insights: Record<string, unknown>) => {\n const maxAttempts = 3;\n for (let i = 0; i < maxAttempts; i++) {\n try {\n await axios.post(`https://chat-insights.getstream.io/insights/${insightType}`, insights);\n } catch (e) {\n await sleep((i + 1) * 3000);\n continue;\n }\n break;\n }\n};\n\nexport function buildWsFatalInsight(connection: StableWSConnection, event: Record<string, unknown>) {\n return {\n ...event,\n ...buildWsBaseInsight(connection),\n };\n}\n\nfunction buildWsBaseInsight(connection: StableWSConnection) {\n const { client } = connection;\n return {\n ready_state: connection.ws?.readyState,\n url: connection._buildUrl(),\n api_key: client.key,\n start_ts: client.insightMetrics.connectionStartTimestamp,\n end_ts: new Date().getTime(),\n auth_type: client.getAuthType(),\n token: client.tokenManager.token,\n user_id: client.userID,\n user_details: client._user,\n device: client.options.device,\n client_id: connection.connectionID,\n ws_details: connection.ws,\n ws_consecutive_failures: client.insightMetrics.wsConsecutiveFailures,\n ws_total_failures: client.insightMetrics.wsTotalFailures,\n request_id: connection.requestID,\n online: typeof navigator !== 'undefined' ? navigator?.onLine : null,\n user_agent: typeof navigator !== 'undefined' ? navigator?.userAgent : null,\n instance_client_id: client.insightMetrics.instanceClientId,\n };\n}\n\nexport function buildWsSuccessAfterFailureInsight(connection: StableWSConnection) {\n return buildWsBaseInsight(connection);\n}\n","import WebSocket from 'isomorphic-ws';\nimport {\n chatCodes,\n convertErrorToJson,\n sleep,\n retryInterval,\n randomId,\n removeConnectionEventListeners,\n addConnectionEventListeners,\n} from './utils';\nimport { buildWsFatalInsight, buildWsSuccessAfterFailureInsight, postInsights } from './insights';\nimport { ConnectAPIResponse, ConnectionOpen, ExtendableGenerics, DefaultGenerics, UR, LogLevel } from './types';\nimport { StreamChat } from './client';\n\n// Type guards to check WebSocket error type\nconst isCloseEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.CloseEvent =>\n (res as WebSocket.CloseEvent).code !== undefined;\n\nconst isErrorEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.ErrorEvent =>\n (res as WebSocket.ErrorEvent).error !== undefined;\n\n/**\n * StableWSConnection - A WS connection that reconnects upon failure.\n * - the browser will sometimes report that you're online or offline\n * - the WS connection can break and fail (there is a 30s health check)\n * - sometimes your WS connection will seem to work while the user is in fact offline\n * - to speed up online/offline detection you can use the window.addEventListener('offline');\n *\n * There are 4 ways in which a connection can become unhealthy:\n * - websocket.onerror is called\n * - websocket.onclose is called\n * - the health check fails and no event is received for ~40 seconds\n * - the browser indicates the connection is now offline\n *\n * There are 2 assumptions we make about the server:\n * - state can be recovered by querying the channel again\n * - if the servers fails to publish a message to the client, the WS connection is destroyed\n */\nexport class StableWSConnection<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n // global from constructor\n client: StreamChat<StreamChatGenerics>;\n\n // local vars\n connectionID?: string;\n connectionOpen?: ConnectAPIResponse<StreamChatGenerics>;\n consecutiveFailures: number;\n pingInterval: number;\n healthCheckTimeoutRef?: NodeJS.Timeout;\n isConnecting: boolean;\n isDisconnected: boolean;\n isHealthy: boolean;\n isResolved?: boolean;\n lastEvent: Date | null;\n connectionCheckTimeout: number;\n connectionCheckTimeoutRef?: NodeJS.Timeout;\n rejectPromise?: (\n reason?: Error & { code?: string | number; isWSFailure?: boolean; StatusCode?: string | number },\n ) => void;\n requestID: string | undefined;\n resolvePromise?: (value: ConnectionOpen<StreamChatGenerics>) => void;\n totalFailures: number;\n ws?: WebSocket;\n wsID: number;\n\n constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {\n /** StreamChat client */\n this.client = client;\n /** consecutive failures influence the duration of the timeout */\n this.consecutiveFailures = 0;\n /** keep track of the total number of failures */\n this.totalFailures = 0;\n /** We only make 1 attempt to reconnect at the same time.. */\n this.isConnecting = false;\n /** To avoid reconnect if client is disconnected */\n this.isDisconnected = false;\n /** Boolean that indicates if the connection promise is resolved */\n this.isResolved = false;\n /** Boolean that indicates if we have a working connection to the server */\n this.isHealthy = false;\n /** Incremented when a new WS connection is made */\n this.wsID = 1;\n /** Store the last event time for health checks */\n this.lastEvent = null;\n /** Send a health check message every 25 seconds */\n this.pingInterval = 25 * 1000;\n this.connectionCheckTimeout = this.pingInterval + 10 * 1000;\n\n addConnectionEventListeners(this.onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'connection:' + msg, { tags: ['connection'], ...extra });\n }\n\n setClient(client: StreamChat<StreamChatGenerics>) {\n this.client = client;\n }\n\n /**\n * connect - Connect to the WS URL\n * the default 15s timeout allows between 2~3 tries\n * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received\n */\n async connect(timeout = 15000) {\n if (this.isConnecting) {\n throw Error(`You've called connect twice, can only attempt 1 connection at the time`);\n }\n\n this.isDisconnected = false;\n\n try {\n const healthCheck = await this._connect();\n this.consecutiveFailures = 0;\n\n this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);\n } catch (error) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n if (error.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {\n this._log('connect() - WS failure due to expired token, so going to try to reload token and reconnect');\n this._reconnect({ refreshToken: true });\n } else if (!error.isWSFailure) {\n // API rejected the connection and we should not retry\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n }\n\n return await this._waitForHealthy(timeout);\n }\n\n /**\n * _waitForHealthy polls the promise connection to see if its resolved until it times out\n * the default 15s timeout allows between 2~3 tries\n * @param timeout duration(ms)\n */\n async _waitForHealthy(timeout = 15000) {\n return Promise.race([\n (async () => {\n const interval = 50; // ms\n for (let i = 0; i <= timeout; i += interval) {\n try {\n return await this.connectionOpen;\n } catch (error) {\n if (i === timeout) {\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n await sleep(interval);\n }\n }\n })(),\n (async () => {\n await sleep(timeout);\n this.isConnecting = false;\n throw new Error(\n JSON.stringify({\n code: '',\n StatusCode: '',\n message: 'initial WS connection could not be established',\n isWSFailure: true,\n }),\n );\n })(),\n ]);\n }\n\n /**\n * Builds and returns the url for websocket.\n * @private\n * @returns url string\n */\n _buildUrl = () => {\n const qs = encodeURIComponent(this.client._buildWSPayload(this.requestID));\n const token = this.client.tokenManager.getToken();\n\n return `${this.client.wsBaseURL}/connect?json=${qs}&api_key=${\n this.client.key\n }&authorization=${token}&stream-auth-type=${this.client.getAuthType()}&X-Stream-Client=${this.client.getUserAgent()}`;\n };\n\n /**\n * disconnect - Disconnect the connection and doesn't recover...\n *\n */\n disconnect(timeout?: number) {\n this._log(`disconnect() - Closing the websocket connection for wsID ${this.wsID}`);\n\n this.wsID += 1;\n this.isConnecting = false;\n this.isDisconnected = true;\n\n // start by removing all the listeners\n if (this.healthCheckTimeoutRef) {\n clearInterval(this.healthCheckTimeoutRef);\n }\n if (this.connectionCheckTimeoutRef) {\n clearInterval(this.connectionCheckTimeoutRef);\n }\n\n removeConnectionEventListeners(this.onlineStatusChanged);\n\n this.isHealthy = false;\n\n // remove ws handlers...\n if (this.ws && this.ws.removeAllListeners) {\n this.ws.removeAllListeners();\n }\n\n let isClosedPromise: Promise<void>;\n // and finally close...\n // Assigning to local here because we will remove it from this before the\n // promise resolves.\n const { ws } = this;\n if (ws && ws.close && ws.readyState === ws.OPEN) {\n isClosedPromise = new Promise((resolve) => {\n const onclose = (event: WebSocket.CloseEvent) => {\n this._log(`disconnect() - resolving isClosedPromise ${event ? 'with' : 'without'} close frame`, { event });\n resolve();\n };\n\n ws.onclose = onclose;\n // In case we don't receive close frame websocket server in time,\n // lets not wait for more than 1 seconds.\n setTimeout(onclose, timeout != null ? timeout : 1000);\n });\n\n this._log(`disconnect() - Manually closed connection by calling client.disconnect()`);\n\n ws.close(chatCodes.WS_CLOSED_SUCCESS, 'Manually closed connection by calling client.disconnect()');\n } else {\n this._log(`disconnect() - ws connection doesn't exist or it is already closed.`);\n isClosedPromise = Promise.resolve();\n }\n\n delete this.ws;\n\n return isClosedPromise;\n }\n\n /**\n * _connect - Connect to the WS endpoint\n *\n * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received\n */\n async _connect() {\n if (this.isConnecting || (this.isDisconnected && this.client.options.enableWSFallback)) return; // simply ignore _connect if it's currently trying to connect\n this.isConnecting = true;\n this.requestID = randomId();\n this.client.insightMetrics.connectionStartTimestamp = new Date().getTime();\n let isTokenReady = false;\n try {\n this._log(`_connect() - waiting for token`);\n await this.client.tokenManager.tokenReady();\n isTokenReady = true;\n } catch (e) {\n // token provider has failed before, so try again\n }\n\n try {\n if (!isTokenReady) {\n this._log(`_connect() - tokenProvider failed before, so going to retry`);\n await this.client.tokenManager.loadToken();\n }\n\n this._setupConnectionPromise();\n const wsURL = this._buildUrl();\n this._log(`_connect() - Connecting to ${wsURL}`, { wsURL, requestID: this.requestID });\n this.ws = new WebSocket(wsURL);\n this.ws.onopen = this.onopen.bind(this, this.wsID);\n this.ws.onclose = this.onclose.bind(this, this.wsID);\n this.ws.onerror = this.onerror.bind(this, this.wsID);\n this.ws.onmessage = this.onmessage.bind(this, this.wsID);\n const response = await this.connectionOpen;\n this.isConnecting = false;\n\n if (response) {\n this.connectionID = response.connection_id;\n if (this.client.insightMetrics.wsConsecutiveFailures > 0 && this.client.options.enableInsights) {\n postInsights(\n 'ws_success_after_failure',\n buildWsSuccessAfterFailureInsight((this as unknown) as StableWSConnection),\n );\n this.client.insightMetrics.wsConsecutiveFailures = 0;\n }\n return response;\n }\n } catch (err) {\n this.isConnecting = false;\n this._log(`_connect() - Error - `, err);\n if (this.client.options.enableInsights) {\n this.client.insightMetrics.wsConsecutiveFailures++;\n this.client.insightMetrics.wsTotalFailures++;\n\n const insights = buildWsFatalInsight((this as unknown) as StableWSConnection, convertErrorToJson(err as Error));\n postInsights?.('ws_fatal', insights);\n }\n throw err;\n }\n }\n\n /**\n * _reconnect - Retry the connection to WS endpoint\n *\n * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available\n *\n * - `interval`\t{int}\t\t\tnumber of ms that function should wait before reconnecting\n * - `refreshToken` {boolean}\treload/refresh user token be refreshed before attempting reconnection.\n */\n async _reconnect(options: { interval?: number; refreshToken?: boolean } = {}): Promise<void> {\n this._log('_reconnect() - Initiating the reconnect');\n\n // only allow 1 connection at the time\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (1) since already connecting or healthy');\n return;\n }\n\n // reconnect in case of on error or on close\n // also reconnect if the health check cycle fails\n let interval = options.interval;\n if (!interval) {\n interval = retryInterval(this.consecutiveFailures);\n }\n // reconnect, or try again after a little while...\n await sleep(interval);\n\n // Check once again if by some other call to _reconnect is active or connection is\n // already restored, then no need to proceed.\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (2) since already connecting or healthy');\n return;\n }\n\n if (this.isDisconnected && this.client.options.enableWSFallback) {\n this._log('_reconnect() - Abort (3) since disconnect() is called');\n return;\n }\n\n this._log('_reconnect() - Destroying current WS connection');\n\n // cleanup the old connection\n this._destroyCurrentWSConnection();\n\n if (options.refreshToken) {\n await this.client.tokenManager.loadToken();\n }\n\n try {\n await this._connect();\n this._log('_reconnect() - Waiting for recoverCallBack');\n await this.client.recoverState();\n this._log('_reconnect() - Finished recoverCallBack');\n\n this.consecutiveFailures = 0;\n } catch (error) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n if (error.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {\n this._log('_reconnect() - WS failure due to expired token, so going to try to reload token and reconnect');\n\n return this._reconnect({ refreshToken: true });\n }\n\n // reconnect on WS failures, don't reconnect if there is a code bug\n if (error.isWSFailure) {\n this._log('_reconnect() - WS failure, so going to try to reconnect');\n\n this._reconnect();\n }\n }\n this._log('_reconnect() - == END ==');\n }\n\n /**\n * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.\n *\n * @param {Event} event Event with type online or offline\n *\n */\n onlineStatusChanged = (event: Event) => {\n if (event.type === 'offline') {\n // mark the connection as down\n this._log('onlineStatusChanged() - Status changing to offline');\n this._setHealth(false);\n } else if (event.type === 'online') {\n // retry right now...\n // We check this.isHealthy, not sure if it's always\n // smart to create a new WS connection if the old one is still up and running.\n // it's possible we didn't miss any messages, so this process is just expensive and not needed.\n this._log(`onlineStatusChanged() - Status changing to online. isHealthy: ${this.isHealthy}`);\n if (!this.isHealthy) {\n this._reconnect({ interval: 10 });\n }\n }\n };\n\n onopen = (wsID: number) => {\n if (this.wsID !== wsID) return;\n\n this._log('onopen() - onopen callback', { wsID });\n };\n\n onmessage = (wsID: number, event: WebSocket.MessageEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onmessage() - onmessage callback', { event, wsID });\n const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;\n\n // we wait till the first message before we consider the connection open..\n // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately\n // after that a ws.onclose..\n if (!this.isResolved && data) {\n this.isResolved = true;\n if (data.error) {\n this.rejectPromise?.(this._errorFromWSEvent(data, false));\n return;\n }\n\n this.resolvePromise?.(data);\n this._setHealth(true);\n }\n\n // trigger the event..\n this.lastEvent = new Date();\n\n if (data && data.type === 'health.check') {\n this.scheduleNextPing();\n }\n\n this.client.handleEvent(event);\n this.scheduleConnectionCheck();\n };\n\n onclose = (wsID: number, event: WebSocket.CloseEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onclose() - onclose callback - ' + event.code, { event, wsID });\n\n if (event.code === chatCodes.WS_CLOSED_SUCCESS) {\n // this is a permanent error raised by stream..\n // usually caused by invalid auth details\n const error = new Error(`WS connection reject with error ${event.reason}`) as Error & WebSocket.CloseEvent;\n\n error.reason = event.reason;\n error.code = event.code;\n error.wasClean = event.wasClean;\n error.target = event.target;\n\n this.rejectPromise?.(error);\n this._log(`onclose() - WS connection reject with error ${event.reason}`, { event });\n } else {\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n\n this._log(`onclose() - WS connection closed. Calling reconnect ...`, { event });\n\n // reconnect if its an abnormal failure\n this._reconnect();\n }\n };\n\n onerror = (wsID: number, event: WebSocket.ErrorEvent) => {\n if (this.wsID !== wsID) return;\n\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n this._log(`onerror() - WS connection resulted into error`, { event });\n\n this._reconnect();\n };\n\n /**\n * _setHealth - Sets the connection to healthy or unhealthy.\n * Broadcasts an event in case the connection status changed.\n *\n * @param {boolean} healthy boolean indicating if the connection is healthy or not\n *\n */\n _setHealth = (healthy: boolean) => {\n if (healthy === this.isHealthy) return;\n\n this.isHealthy = healthy;\n\n if (this.isHealthy) {\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n return;\n }\n\n // we're offline, wait few seconds and fire and event if still offline\n setTimeout(() => {\n if (this.isHealthy) return;\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n }, 5000);\n };\n\n /**\n * _errorFromWSEvent - Creates an error object for the WS event\n *\n */\n _errorFromWSEvent = (event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent, isWSFailure = true) => {\n let code;\n let statusCode;\n let message;\n if (isCloseEvent(event)) {\n code = event.code;\n statusCode = 'unknown';\n message = event.reason;\n }\n\n if (isErrorEvent(event)) {\n code = event.error.code;\n statusCode = event.error.StatusCode;\n message = event.error.message;\n }\n\n // Keeping this `warn` level log, to avoid cluttering of error logs from ws failures.\n this._log(`_errorFromWSEvent() - WS failed with code ${code}`, { event }, 'warn');\n\n const error = new Error(`WS failed with code ${code} and reason - ${message}`) as Error & {\n code?: string | number;\n isWSFailure?: boolean;\n StatusCode?: string | number;\n };\n error.code = code;\n /**\n * StatusCode does not exist on any event types but has been left\n * as is to preserve JS functionality during the TS implementation\n */\n error.StatusCode = statusCode;\n error.isWSFailure = isWSFailure;\n return error;\n };\n\n /**\n * _destroyCurrentWSConnection - Removes the current WS connection\n *\n */\n _destroyCurrentWSConnection() {\n // increment the ID, meaning we will ignore all messages from the old\n // ws connection from now on.\n this.wsID += 1;\n\n try {\n this?.ws?.removeAllListeners();\n this?.ws?.close();\n } catch (e) {\n // we don't care\n }\n }\n\n /**\n * _setupPromise - sets up the this.connectOpen promise\n */\n _setupConnectionPromise = () => {\n this.isResolved = false;\n /** a promise that is resolved once ws.open is called */\n this.connectionOpen = new Promise<ConnectionOpen<StreamChatGenerics>>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n };\n\n /**\n * Schedules a next health check ping for websocket.\n */\n scheduleNextPing = () => {\n if (this.healthCheckTimeoutRef) {\n clearTimeout(this.healthCheckTimeoutRef);\n }\n\n // 30 seconds is the recommended interval (messenger uses this)\n this.healthCheckTimeoutRef = setTimeout(() => {\n // send the healthcheck.., server replies with a health check event\n const data = [{ type: 'health.check', client_id: this.client.clientID }];\n // try to send on the connection\n try {\n this.ws?.send(JSON.stringify(data));\n } catch (e) {\n // error will already be detected elsewhere\n }\n }, this.pingInterval);\n };\n\n /**\n * scheduleConnectionCheck - schedules a check for time difference between last received event and now.\n * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs\n * to be reconnected.\n */\n scheduleConnectionCheck = () => {\n if (this.connectionCheckTimeoutRef) {\n clearTimeout(this.connectionCheckTimeoutRef);\n }\n\n this.connectionCheckTimeoutRef = setTimeout(() => {\n const now = new Date();\n if (this.lastEvent && now.getTime() - this.lastEvent.getTime() > this.connectionCheckTimeout) {\n this._log('scheduleConnectionCheck - going to reconnect');\n this._setHealth(false);\n this._reconnect();\n }\n }, this.connectionCheckTimeout);\n };\n}\n","import jwt, { Secret, SignOptions } from 'jsonwebtoken';\nimport crypto from 'crypto';\nimport { encodeBase64, decodeBase64 } from './base64';\nimport { UR } from './types';\n\n/**\n * Creates the JWT token that can be used for a UserSession\n * @method JWTUserToken\n * @memberof signing\n * @private\n * @param {Secret} apiSecret - API Secret key\n * @param {string} userId - The user_id key in the JWT payload\n * @param {UR} [extraData] - Extra that should be part of the JWT token\n * @param {SignOptions} [jwtOptions] - Options that can be past to jwt.sign\n * @return {string} JWT Token\n */\nexport function JWTUserToken(apiSecret: Secret, userId: string, extraData: UR = {}, jwtOptions: SignOptions = {}) {\n if (typeof userId !== 'string') {\n throw new TypeError('userId should be a string');\n }\n\n const payload: { user_id: string } & UR = {\n user_id: userId,\n ...extraData,\n };\n\n // make sure we return a clear error when jwt is shimmed (ie. browser build)\n if (jwt == null || jwt.sign == null) {\n throw Error(\n `Unable to find jwt crypto, if you are getting this error is probably because you are trying to generate tokens on browser or React Native (or other environment where crypto functions are not available). Please Note: token should only be generated server-side.`,\n );\n }\n\n const opts: SignOptions = Object.assign({ algorithm: 'HS256', noTimestamp: true }, jwtOptions);\n\n if (payload.iat) {\n opts.noTimestamp = false;\n }\n return jwt.sign(payload, apiSecret, opts);\n}\n\nexport function JWTServerToken(apiSecret: Secret, jwtOptions: SignOptions = {}) {\n const payload = {\n server: true,\n };\n\n const opts: SignOptions = Object.assign({ algorithm: 'HS256', noTimestamp: true }, jwtOptions);\n return jwt.sign(payload, apiSecret, opts);\n}\n\nexport function UserFromToken(token: string) {\n const fragments = token.split('.');\n if (fragments.length !== 3) {\n return '';\n }\n const b64Payload = fragments[1];\n const payload = decodeBase64(b64Payload);\n const data = JSON.parse(payload);\n return data.user_id as string;\n}\n\n/**\n *\n * @param {string} userId the id of the user\n * @return {string}\n */\nexport function DevToken(userId: string) {\n return [\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', //{\"alg\": \"HS256\", \"typ\": \"JWT\"}\n encodeBase64(JSON.stringify({ user_id: userId })),\n 'devtoken', // hardcoded signature\n ].join('.');\n}\n\n/**\n *\n * @param {string | Buffer} body the signed message\n * @param {string} secret the shared secret used to generate the signature (Stream API secret)\n * @param {string} signature the signature to validate\n * @return {boolean}\n */\nexport function CheckSignature(body: string | Buffer, secret: string, signature: string) {\n const key = Buffer.from(secret, 'utf8');\n const hash = crypto.createHmac('sha256', key).update(body).digest('hex');\n\n try {\n return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));\n } catch {\n return false;\n }\n}\n","export default null;","export default null;","import axios, { AxiosRequestConfig, CancelTokenSource } from 'axios';\nimport { StreamChat } from './client';\nimport { addConnectionEventListeners, removeConnectionEventListeners, retryInterval, sleep } from './utils';\nimport { isAPIError, isConnectionIDError, isErrorRetryable } from './errors';\nimport { ConnectionOpen, Event, UR, ExtendableGenerics, DefaultGenerics, LogLevel } from './types';\n\nexport enum ConnectionState {\n Closed = 'CLOSED',\n Connected = 'CONNECTED',\n Connecting = 'CONNECTING',\n Disconnected = 'DISCONNECTED',\n Init = 'INIT',\n}\n\nexport class WSConnectionFallback<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n client: StreamChat<StreamChatGenerics>;\n state: ConnectionState;\n consecutiveFailures: number;\n connectionID?: string;\n cancelToken?: CancelTokenSource;\n\n constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {\n this.client = client;\n this.state = ConnectionState.Init;\n this.consecutiveFailures = 0;\n\n addConnectionEventListeners(this._onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'WSConnectionFallback:' + msg, { tags: ['connection_fallback', 'connection'], ...extra });\n }\n\n _setState(state: ConnectionState) {\n this._log(`_setState() - ${state}`);\n\n // transition from connecting => connected\n if (this.state === ConnectionState.Connecting && state === ConnectionState.Connected) {\n this.client.dispatchEvent({ type: 'connection.changed', online: true });\n }\n\n if (state === ConnectionState.Closed || state === ConnectionState.Disconnected) {\n this.client.dispatchEvent({ type: 'connection.changed', online: false });\n }\n\n this.state = state;\n }\n\n /** @private */\n _onlineStatusChanged = (event: { type: string }) => {\n this._log(`_onlineStatusChanged() - ${event.type}`);\n\n if (event.type === 'offline') {\n this._setState(ConnectionState.Closed);\n this.cancelToken?.cancel('disconnect() is called');\n this.cancelToken = undefined;\n return;\n }\n\n if (event.type === 'online' && this.state === ConnectionState.Closed) {\n this.connect(true);\n }\n };\n\n /** @private */\n _req = async <T = UR>(params: UR, config: AxiosRequestConfig, retry: boolean): Promise<T> => {\n if (!this.cancelToken && !params.close) {\n this.cancelToken = axios.CancelToken.source();\n }\n\n try {\n const res = await this.client.doAxiosRequest<T>(\n 'get',\n (this.client.baseURL as string).replace(':3030', ':8900') + '/longpoll', // replace port if present for testing with local API\n undefined,\n {\n config: { ...config, cancelToken: this.cancelToken?.token },\n params,\n },\n );\n\n this.consecutiveFailures = 0; // always reset in case of no error\n return res;\n } catch (err) {\n this.consecutiveFailures += 1;\n\n if (retry && isErrorRetryable(err)) {\n this._log(`_req() - Retryable error, retrying request`);\n await sleep(retryInterval(this.consecutiveFailures));\n return this._req<T>(params, config, retry);\n }\n\n throw err;\n }\n };\n\n /** @private */\n _poll = async () => {\n while (this.state === ConnectionState.Connected) {\n try {\n const data = await this._req<{\n events: Event<StreamChatGenerics>[];\n }>({}, { timeout: 30000 }, true); // 30s => API responds in 20s if there is no event\n\n if (data.events?.length) {\n for (let i = 0; i < data.events.length; i++) {\n this.client.dispatchEvent(data.events[i]);\n }\n }\n } catch (err) {\n if (axios.isCancel(err)) {\n this._log(`_poll() - axios canceled request`);\n return;\n }\n\n /** client.doAxiosRequest will take care of TOKEN_EXPIRED error */\n\n if (isConnectionIDError(err)) {\n this._log(`_poll() - ConnectionID error, connecting without ID...`);\n this._setState(ConnectionState.Disconnected);\n this.connect(true);\n return;\n }\n\n if (isAPIError(err) && !isErrorRetryable(err)) {\n this._setState(ConnectionState.Closed);\n return;\n }\n\n await sleep(retryInterval(this.consecutiveFailures));\n }\n }\n };\n\n /**\n * connect try to open a longpoll request\n * @param reconnect should be false for first call and true for subsequent calls to keep the connection alive and call recoverState\n */\n connect = async (reconnect = false) => {\n if (this.state === ConnectionState.Connecting) {\n this._log('connect() - connecting already in progress', { reconnect }, 'warn');\n return;\n }\n if (this.state === ConnectionState.Connected) {\n this._log('connect() - already connected and polling', { reconnect }, 'warn');\n return;\n }\n\n this._setState(ConnectionState.Connecting);\n this.connectionID = undefined; // connect should be sent with empty connection_id so API creates one\n try {\n const { event } = await this._req<{ event: ConnectionOpen<StreamChatGenerics> }>(\n { json: this.client._buildWSPayload() },\n { timeout: 8000 }, // 8s\n reconnect,\n );\n\n this._setState(ConnectionState.Connected);\n this.connectionID = event.connection_id;\n // @ts-expect-error\n this.client.dispatchEvent(event);\n this._poll();\n if (reconnect) {\n this.client.recoverState();\n }\n return event;\n } catch (err) {\n this._setState(ConnectionState.Closed);\n throw err;\n }\n };\n\n /**\n * isHealthy checks if there is a connectionID and connection is in Connected state\n */\n isHealthy = () => {\n return !!this.connectionID && this.state === ConnectionState.Connected;\n };\n\n disconnect = async (timeout = 2000) => {\n removeConnectionEventListeners(this._onlineStatusChanged);\n\n this._setState(ConnectionState.Disconnected);\n this.cancelToken?.cancel('disconnect() is called');\n this.cancelToken = undefined;\n\n const connection_id = this.connectionID;\n this.connectionID = undefined;\n\n try {\n await this._req({ close: true, connection_id }, { timeout }, false);\n this._log(`disconnect() - Closed connectionID`);\n } catch (err) {\n this._log(`disconnect() - Failed`, { err }, 'error');\n }\n };\n}\n","import { Secret } from 'jsonwebtoken';\nimport { UserFromToken, JWTServerToken, JWTUserToken } from './signing';\nimport { isFunction } from './utils';\nimport { TokenOrProvider, ExtendableGenerics, DefaultGenerics, UserResponse } from './types';\n\n/**\n * TokenManager\n *\n * Handles all the operations around user token.\n */\nexport class TokenManager<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n loadTokenPromise: Promise<string> | null;\n type: 'static' | 'provider';\n secret?: Secret;\n token?: string;\n tokenProvider?: TokenOrProvider;\n user?: UserResponse<StreamChatGenerics>;\n /**\n * Constructor\n *\n * @param {Secret} secret\n */\n constructor(secret?: Secret) {\n this.loadTokenPromise = null;\n if (secret) {\n this.secret = secret;\n }\n\n this.type = 'static';\n\n if (this.secret) {\n this.token = JWTServerToken(this.secret);\n }\n }\n\n /**\n * Set the static string token or token provider.\n * Token provider should return a token string or a promise which resolves to string token.\n *\n * @param {TokenOrProvider} tokenOrProvider\n * @param {UserResponse<StreamChatGenerics>} user\n */\n setTokenOrProvider = async (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {\n this.validateToken(tokenOrProvider, user);\n this.user = user;\n\n if (isFunction(tokenOrProvider)) {\n this.tokenProvider = tokenOrProvider;\n this.type = 'provider';\n }\n\n if (typeof tokenOrProvider === 'string') {\n this.token = tokenOrProvider;\n this.type = 'static';\n }\n\n if (!tokenOrProvider && this.user && this.secret) {\n this.token = JWTUserToken(this.secret, user.id, {}, {});\n this.type = 'static';\n }\n\n await this.loadToken();\n };\n\n /**\n * Resets the token manager.\n * Useful for client disconnection or switching user.\n */\n reset = () => {\n this.token = undefined;\n this.tokenProvider = undefined;\n this.type = 'static';\n this.user = undefined;\n this.loadTokenPromise = null;\n };\n\n // Validates the user token.\n validateToken = (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {\n // allow empty token for anon user\n if (user && user.anon && !tokenOrProvider) return;\n\n // Don't allow empty token for non-server side client.\n if (!this.secret && !tokenOrProvider) {\n throw new Error('User token can not be empty');\n }\n\n if (tokenOrProvider && typeof tokenOrProvider !== 'string' && !isFunction(tokenOrProvider)) {\n throw new Error('user token should either be a string or a function');\n }\n\n if (typeof tokenOrProvider === 'string') {\n // Allow empty token for anonymous users\n if (user.anon && tokenOrProvider === '') return;\n\n const tokenUserId = UserFromToken(tokenOrProvider);\n if (tokenOrProvider != null && (tokenUserId == null || tokenUserId === '' || tokenUserId !== user.id)) {\n throw new Error('userToken does not have a user_id or is not matching with user.id');\n }\n }\n };\n\n // Resolves when token is ready. This function is simply to check if loadToken is in progress, in which\n // case a function should wait.\n tokenReady = () => this.loadTokenPromise;\n\n // Fetches a token from tokenProvider function and sets in tokenManager.\n // In case of static token, it will simply resolve to static token.\n loadToken = () => {\n // eslint-disable-next-line no-async-promise-executor\n this.loadTokenPromise = new Promise(async (resolve, reject) => {\n if (this.type === 'static') {\n return resolve(this.token as string);\n }\n\n if (this.tokenProvider && typeof this.tokenProvider !== 'string') {\n try {\n this.token = await this.tokenProvider();\n } catch (e) {\n return reject(new Error(`Call to tokenProvider failed with message: ${e}`));\n }\n resolve(this.token);\n }\n });\n\n return this.loadTokenPromise;\n };\n\n // Returns a current token\n getToken = () => {\n if (this.token) {\n return this.token;\n }\n\n if (this.user && this.user.anon && !this.token) {\n return this.token;\n }\n\n if (this.secret) {\n return JWTServerToken(this.secret);\n }\n\n throw new Error(\n `Both secret and user tokens are not set. Either client.connectUser wasn't called or client.disconnect was called`,\n );\n };\n\n isStatic = () => this.type === 'static';\n}\n","import { AxiosResponse } from 'axios';\nimport { APIErrorResponse } from './types';\n\nexport const APIErrorCodes: Record<string, { name: string; retryable: boolean }> = {\n '-1': { name: 'InternalSystemError', retryable: true },\n '2': { name: 'AccessKeyError', retryable: false },\n '3': { name: 'AuthenticationFailedError', retryable: true },\n '4': { name: 'InputError', retryable: false },\n '6': { name: 'DuplicateUsernameError', retryable: false },\n '9': { name: 'RateLimitError', retryable: true },\n '16': { name: 'DoesNotExistError', retryable: false },\n '17': { name: 'NotAllowedError', retryable: false },\n '18': { name: 'EventNotSupportedError', retryable: false },\n '19': { name: 'ChannelFeatureNotSupportedError', retryable: false },\n '20': { name: 'MessageTooLongError', retryable: false },\n '21': { name: 'MultipleNestingLevelError', retryable: false },\n '22': { name: 'PayloadTooBigError', retryable: false },\n '23': { name: 'RequestTimeoutError', retryable: true },\n '24': { name: 'MaxHeaderSizeExceededError', retryable: false },\n '40': { name: 'AuthErrorTokenExpired', retryable: false },\n '41': { name: 'AuthErrorTokenNotValidYet', retryable: false },\n '42': { name: 'AuthErrorTokenUsedBeforeIssuedAt', retryable: false },\n '43': { name: 'AuthErrorTokenSignatureInvalid', retryable: false },\n '44': { name: 'CustomCommandEndpointMissingError', retryable: false },\n '45': { name: 'CustomCommandEndpointCallError', retryable: true },\n '46': { name: 'ConnectionIDNotFoundError', retryable: false },\n '60': { name: 'CoolDownError', retryable: true },\n '69': { name: 'ErrWrongRegion', retryable: false },\n '70': { name: 'ErrQueryChannelPermissions', retryable: false },\n '71': { name: 'ErrTooManyConnections', retryable: true },\n '99': { name: 'AppSuspendedError', retryable: false },\n};\n\ntype APIError = Error & { code: number; isWSFailure?: boolean };\n\nexport function isAPIError(error: Error): error is APIError {\n return (error as APIError).code !== undefined;\n}\n\nexport function isErrorRetryable(error: APIError) {\n if (!error.code) return false;\n const err = APIErrorCodes[`${error.code}`];\n if (!err) return false;\n return err.retryable;\n}\n\nexport function isConnectionIDError(error: APIError) {\n return error.code === 46; // ConnectionIDNotFoundError\n}\n\nexport function isWSFailure(err: APIError): boolean {\n if (typeof err.isWSFailure === 'boolean') {\n return err.isWSFailure;\n }\n\n try {\n return JSON.parse(err.message).isWSFailure;\n } catch (_) {\n return false;\n }\n}\n\nexport function isErrorResponse(res: AxiosResponse<unknown>): res is AxiosResponse<APIErrorResponse> {\n return !res.status || res.status < 200 || 300 <= res.status;\n}\n","import { StreamChat } from './client';\nimport {\n DefaultGenerics,\n ExtendableGenerics,\n QuerySegmentTargetsFilter,\n SegmentData,\n SegmentResponse,\n SortParam,\n} from './types';\n\ntype SegmentType = 'user' | 'channel';\n\ntype SegmentUpdatableFields = {\n description?: string;\n filter?: {};\n name?: string;\n};\n\nexport class Segment<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n type: SegmentType;\n id: string | null;\n client: StreamChat<StreamChatGenerics>;\n data?: SegmentData | SegmentResponse;\n\n constructor(client: StreamChat<StreamChatGenerics>, type: SegmentType, id: string | null, data?: SegmentData) {\n this.client = client;\n this.type = type;\n this.id = id;\n this.data = data;\n }\n\n async create() {\n const body = {\n name: this.data?.name,\n filter: this.data?.filter,\n description: this.data?.description,\n all_sender_channels: this.data?.all_sender_channels,\n all_users: this.data?.all_users,\n };\n\n return this.client.createSegment(this.type, this.id, body);\n }\n\n verifySegmentId() {\n if (!this.id) {\n throw new Error(\n 'Segment id is missing. Either create the segment using segment.create() or set the id during instantiation - const segment = client.segment(id)',\n );\n }\n }\n\n async get() {\n this.verifySegmentId();\n return this.client.getSegment(this.id as string);\n }\n\n async update(data: Partial<SegmentUpdatableFields>) {\n this.verifySegmentId();\n\n return this.client.updateSegment(this.id as string, data);\n }\n\n async addTargets(targets: string[]) {\n this.verifySegmentId();\n return this.client.addSegmentTargets(this.id as string, targets);\n }\n\n async removeTargets(targets: string[]) {\n this.verifySegmentId();\n return this.client.removeSegmentTargets(this.id as string, targets);\n }\n\n async delete() {\n this.verifySegmentId();\n return this.client.deleteSegment(this.id as string);\n }\n\n async targetExists(targetId: string) {\n this.verifySegmentId();\n return this.client.segmentTargetExists(this.id as string, targetId);\n }\n\n async queryTargets(filter: QuerySegmentTargetsFilter | null = {}, sort: SortParam[] | null | [] = [], options = {}) {\n this.verifySegmentId();\n\n return this.client.querySegmentTargets(this.id as string, filter, sort, options);\n }\n}\n","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import _typeof from \"@babel/runtime/helpers/typeof\";\nimport assertThisInitialized from \"./assertThisInitialized.js\";\nexport default function _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError(\"Derived constructors may only return object or undefined\");\n }\n\n return assertThisInitialized(self);\n}","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","export default function _isNativeReflectConstruct() {\n if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === \"function\") return true;\n\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nexport default function _construct(Parent, args, Class) {\n if (isNativeReflectConstruct()) {\n _construct = Reflect.construct;\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n }\n\n return _construct.apply(null, arguments);\n}","import getPrototypeOf from \"./getPrototypeOf.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeFunction from \"./isNativeFunction.js\";\nimport construct from \"./construct.js\";\nexport default function _wrapNativeSuper(Class) {\n var _cache = typeof Map === \"function\" ? new Map() : undefined;\n\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !isNativeFunction(Class)) return Class;\n\n if (typeof Class !== \"function\") {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n if (typeof _cache !== \"undefined\") {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return construct(Class, arguments, getPrototypeOf(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return setPrototypeOf(Wrapper, Class);\n };\n\n return _wrapNativeSuper(Class);\n}","export default function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf(\"[native code]\") !== -1;\n}","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { StableWSConnection } from './connection';\nimport { EVENT_MAP } from './events';\nimport { Role } from './permissions';\n\n/**\n * Utility Types\n */\n\nexport type ArrayOneOrMore<T> = {\n 0: T;\n} & Array<T>;\n\nexport type ArrayTwoOrMore<T> = {\n 0: T;\n 1: T;\n} & Array<T>;\n\nexport type KnownKeys<T> = {\n [K in keyof T]: string extends K ? never : number extends K ? never : K;\n} extends { [_ in keyof T]: infer U }\n ? U\n : never;\n\nexport type RequireAtLeastOne<T> = {\n [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;\n}[keyof T];\n\nexport type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &\n {\n [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>;\n }[Keys];\n\n/* Unknown Record */\nexport type UR = Record<string, unknown>;\nexport type UnknownType = UR; //alias to avoid breaking change\n\nexport type DefaultGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: LiteralStringForUnion;\n eventType: UR;\n memberType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type ExtendableGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: string;\n eventType: UR;\n memberType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type Unpacked<T> = T extends (infer U)[]\n ? U // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : T extends (...args: any[]) => infer U\n ? U\n : T extends Promise<infer U>\n ? U\n : T;\n\n/**\n * Response Types\n */\n\nexport type APIResponse = {\n duration: string;\n};\n\nexport type AppSettingsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n app?: {\n // TODO\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call_types: any;\n channel_configs: Record<\n string,\n {\n reminders: boolean;\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n commands?: CommandVariants<StreamChatGenerics>[];\n connect_events?: boolean;\n created_at?: string;\n custom_events?: boolean;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n replies?: boolean;\n search?: boolean;\n typing_events?: boolean;\n updated_at?: string;\n uploads?: boolean;\n url_enrichment?: boolean;\n }\n >;\n reminders_interval: number;\n agora_options?: AgoraOptions | null;\n async_moderation_config?: AsyncModerationOptions;\n async_url_enrich_enabled?: boolean;\n auto_translation_enabled?: boolean;\n before_message_send_hook_url?: string;\n campaign_enabled?: boolean;\n cdn_expiration_seconds?: number;\n custom_action_handler_url?: string;\n datadog_info?: {\n api_key: string;\n site: string;\n enabled?: boolean;\n };\n disable_auth_checks?: boolean;\n disable_permissions_checks?: boolean;\n enforce_unique_usernames?: 'no' | 'app' | 'team';\n file_upload_config?: FileUploadConfig;\n geofences?: Array<{\n country_codes: Array<string>;\n description: string;\n name: string;\n type: string;\n }>;\n grants?: Record<string, string[]>;\n hms_options?: HMSOptions | null;\n image_moderation_enabled?: boolean;\n image_upload_config?: FileUploadConfig;\n multi_tenant_enabled?: boolean;\n name?: string;\n organization?: string;\n permission_version?: string;\n policies?: Record<string, Policy[]>;\n poll_enabled?: boolean;\n push_notifications?: {\n offline_only: boolean;\n version: string;\n apn?: APNConfig;\n firebase?: FirebaseConfig;\n huawei?: HuaweiConfig;\n providers?: PushProviderConfig[];\n xiaomi?: XiaomiConfig;\n };\n revoke_tokens_issued_before?: string | null;\n search_backend?: 'disabled' | 'elasticsearch' | 'postgres';\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n suspended?: boolean;\n suspended_explanation?: string;\n user_search_disallowed_roles?: string[] | null;\n video_provider?: string;\n webhook_events?: Array<string>;\n webhook_url?: string;\n };\n};\n\nexport type ModerationResult = {\n action: string;\n created_at: string;\n message_id: string;\n updated_at: string;\n user_bad_karma: boolean;\n user_karma: number;\n blocked_word?: string;\n blocklist_name?: string;\n moderated_by?: string;\n};\n\nexport type AutomodDetails = {\n action?: string;\n image_labels?: Array<string>;\n original_message_type?: string;\n result?: ModerationResult;\n};\n\nexport type FlagDetails = {\n automod?: AutomodDetails;\n};\n\nexport type Flag<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n created_by_automod: boolean;\n updated_at: string;\n details?: FlagDetails;\n target_message?: MessageResponse<StreamChatGenerics>;\n target_user?: UserResponse<StreamChatGenerics>;\n user?: UserResponse<StreamChatGenerics>;\n};\n\nexport type FlagsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flags?: Array<Flag<StreamChatGenerics>>;\n};\n\nexport type MessageFlagsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flags?: Array<{\n message: MessageResponse<StreamChatGenerics>;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n created_at?: string;\n created_by_automod?: boolean;\n moderation_result?: ModerationResult;\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n }>;\n};\n\nexport type FlagReport<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n flags_count: number;\n id: string;\n message: MessageResponse<StreamChatGenerics>;\n user: UserResponse<StreamChatGenerics>;\n created_at?: string;\n details?: FlagDetails;\n first_reporter?: UserResponse<StreamChatGenerics>;\n review_result?: string;\n reviewed_at?: string;\n reviewed_by?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n};\n\nexport type FlagReportsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag_reports: Array<FlagReport<StreamChatGenerics>>;\n};\n\nexport type ReviewFlagReportResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag_report: FlagReport<StreamChatGenerics>;\n};\n\nexport type BannedUsersResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n bans?: Array<{\n user: UserResponse<StreamChatGenerics>;\n banned_by?: UserResponse<StreamChatGenerics>;\n channel?: ChannelResponse<StreamChatGenerics>;\n expires?: string;\n ip_ban?: boolean;\n reason?: string;\n timeout?: number;\n }>;\n};\n\nexport type BlockListResponse = BlockList & {\n created_at?: string;\n type?: string;\n updated_at?: string;\n};\n\nexport type ChannelResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['channelType'] & {\n cid: string;\n disabled: boolean;\n frozen: boolean;\n id: string;\n type: string;\n auto_translation_enabled?: boolean;\n auto_translation_language?: TranslationLanguages | '';\n config?: ChannelConfigWithInfo<StreamChatGenerics>;\n cooldown?: number;\n created_at?: string;\n created_by?: UserResponse<StreamChatGenerics> | null;\n created_by_id?: string;\n deleted_at?: string;\n hidden?: boolean;\n invites?: string[];\n joined?: boolean;\n last_message_at?: string;\n member_count?: number;\n members?: ChannelMemberResponse<StreamChatGenerics>[];\n muted?: boolean;\n name?: string;\n own_capabilities?: string[];\n team?: string;\n truncated_at?: string;\n truncated_by?: UserResponse<StreamChatGenerics>;\n truncated_by_id?: string;\n updated_at?: string;\n};\n\nexport type QueryReactionsOptions = Pager;\n\nexport type QueryReactionsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n reactions: ReactionResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type QueryChannelsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channels: Omit<ChannelAPIResponse<StreamChatGenerics>, keyof APIResponse>[];\n};\n\nexport type QueryChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n ChannelAPIResponse<StreamChatGenerics>;\n\nexport type ChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n messages: MessageResponse<StreamChatGenerics>[];\n pinned_messages: MessageResponse<StreamChatGenerics>[];\n hidden?: boolean;\n membership?: ChannelMemberResponse<StreamChatGenerics> | null;\n pending_messages?: PendingMessageResponse<StreamChatGenerics>[];\n read?: ReadResponse<StreamChatGenerics>[];\n threads?: ThreadResponse[];\n watcher_count?: number;\n watchers?: UserResponse<StreamChatGenerics>[];\n};\n\nexport type ChannelUpdateOptions = {\n hide_history?: boolean;\n skip_push?: boolean;\n};\n\nexport type ChannelMemberAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n members: ChannelMemberResponse<StreamChatGenerics>[];\n};\n\nexport type ChannelMemberUpdates<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & {\n archived?: boolean;\n channel_role?: Role;\n pinned?: boolean;\n};\n\nexport type ChannelMemberResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & {\n archived_at?: string;\n ban_expires?: string;\n banned?: boolean;\n channel_role?: Role;\n created_at?: string;\n invite_accepted_at?: string;\n invite_rejected_at?: string;\n invited?: boolean;\n is_moderator?: boolean;\n notifications_muted?: boolean;\n pinned_at?: string;\n role?: string;\n shadow_banned?: boolean;\n status?: InviteStatus;\n updated_at?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PartialUpdateMemberAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel_member: ChannelMemberResponse<StreamChatGenerics>;\n};\n\nexport type CheckPushResponse = APIResponse & {\n device_errors?: {\n [deviceID: string]: {\n error_message?: string;\n provider?: PushProvider;\n provider_name?: string;\n };\n };\n general_errors?: string[];\n rendered_apn_template?: string;\n rendered_firebase_template?: string;\n rendered_message?: {};\n skip_devices?: boolean;\n};\n\nexport type CheckSQSResponse = APIResponse & {\n status: string;\n data?: {};\n error?: string;\n};\n\nexport type CheckSNSResponse = APIResponse & {\n status: string;\n data?: {};\n error?: string;\n};\n\nexport type CommandResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Partial<CreatedAtUpdatedAt> & {\n args?: string;\n description?: string;\n name?: CommandVariants<StreamChatGenerics>;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type ConnectAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Promise<void | ConnectionOpen<StreamChatGenerics>>;\n\nexport type CreateChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id'> & {\n created_at: string;\n updated_at: string;\n grants?: Record<string, string[]>;\n };\n\nexport type CreateCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n command: CreateCommandOptions<StreamChatGenerics> & CreatedAtUpdatedAt;\n};\n\nexport type DeleteChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n};\n\nexport type DeleteCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n name?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type EventAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n event: Event<StreamChatGenerics>;\n};\n\nexport type ExportChannelResponse = {\n task_id: string;\n};\n\nexport type ExportUsersResponse = {\n task_id: string;\n};\n\nexport type ExportChannelStatusResponse = {\n created_at?: string;\n error?: {};\n result?: {};\n updated_at?: string;\n};\n\nexport type FlagMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag: {\n created_at: string;\n created_by_automod: boolean;\n target_message_id: string;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n channel_cid?: string;\n details?: Object; // Any JSON\n message_user_id?: string;\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: string;\n };\n review_queue_item_id?: string;\n};\n\nexport type FlagUserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag: {\n created_at: string;\n created_by_automod: boolean;\n target_user: UserResponse<StreamChatGenerics>;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n details?: Object; // Any JSON\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: string;\n };\n review_queue_item_id?: string;\n};\n\nexport type FormatMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'created_at' | 'pinned_at' | 'updated_at' | 'deleted_at' | 'status'\n> &\n StreamChatGenerics['messageType'] & {\n created_at: Date;\n deleted_at: Date | null;\n pinned_at: Date | null;\n status: string;\n updated_at: Date;\n };\n\nexport type GetChannelTypeResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id' | 'commands'> & {\n created_at: string;\n updated_at: string;\n commands?: CommandResponse<StreamChatGenerics>[];\n grants?: Record<string, string[]>;\n };\n\nexport type GetCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n CreateCommandOptions<StreamChatGenerics> &\n CreatedAtUpdatedAt;\n\nexport type GetMessageAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = SendMessageAPIResponse<StreamChatGenerics>;\n\nexport interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics> {\n // FIXME: according to OpenAPI, `channel` could be undefined but since cid is provided I'll asume that it's wrong\n channel: ChannelResponse<SCG>;\n channel_cid: string;\n created_at: string;\n created_by_user_id: string;\n latest_replies: Array<MessageResponse<SCG>>;\n parent_message: MessageResponse<SCG>;\n parent_message_id: string;\n title: string;\n updated_at: string;\n created_by?: UserResponse<SCG>;\n deleted_at?: string;\n last_message_at?: string;\n participant_count?: number;\n read?: Array<ReadResponse<SCG>>;\n reply_count?: number;\n thread_participants?: Array<{\n channel_cid: string;\n created_at: string;\n last_read_at: string;\n last_thread_message_at?: string;\n left_thread_at?: string;\n thread_id?: string;\n user?: UserResponse<SCG>;\n user_id?: string;\n }>;\n}\n\n// TODO: Figure out a way to strongly type set and unset.\nexport type PartialThreadUpdate = {\n set?: Partial<Record<string, unknown>>;\n unset?: Array<string>;\n};\n\nexport type QueryThreadsOptions = {\n limit?: number;\n member_limit?: number;\n next?: string;\n participant_limit?: number;\n reply_limit?: number;\n watch?: boolean;\n};\n\nexport type QueryThreadsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n threads: ThreadResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type GetThreadOptions = {\n member_limit?: number;\n participant_limit?: number;\n reply_limit?: number;\n watch?: boolean;\n};\n\nexport type GetThreadAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n thread: ThreadResponse<StreamChatGenerics>;\n};\n\nexport type GetMultipleMessagesAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n};\n\nexport type GetRateLimitsResponse = APIResponse & {\n android?: RateLimitsMap;\n ios?: RateLimitsMap;\n server_side?: RateLimitsMap;\n web?: RateLimitsMap;\n};\n\nexport type GetReactionsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n reactions: ReactionResponse<StreamChatGenerics>[];\n};\n\nexport type GetRepliesAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n};\n\nexport type GetUnreadCountAPIResponse = APIResponse & {\n channel_type: {\n channel_count: number;\n channel_type: string;\n unread_count: number;\n }[];\n channels: {\n channel_id: string;\n last_read: string;\n unread_count: number;\n }[];\n threads: {\n last_read: string;\n last_read_message_id: string;\n parent_message_id: string;\n unread_count: number;\n }[];\n total_unread_count: number;\n total_unread_threads_count: number;\n};\n\nexport type GetUnreadCountBatchAPIResponse = APIResponse & {\n counts_by_user: { [userId: string]: GetUnreadCountAPIResponse };\n};\n\nexport type ListChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel_types: Record<\n string,\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id' | 'commands'> & {\n commands: CommandResponse<StreamChatGenerics>[];\n created_at: string;\n updated_at: string;\n grants?: Record<string, string[]>;\n }\n >;\n};\n\nexport type ListChannelTypesAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ListChannelResponse<StreamChatGenerics>;\n\nexport type ListCommandsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n commands: Array<CreateCommandOptions<StreamChatGenerics> & Partial<CreatedAtUpdatedAt>>;\n};\n\nexport type MuteChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel_mute: ChannelMute<StreamChatGenerics>;\n own_user: OwnUserResponse<StreamChatGenerics>;\n channel_mutes?: ChannelMute<StreamChatGenerics>[];\n mute?: MuteResponse<StreamChatGenerics>;\n};\n\nexport type MessageResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MessageResponseBase<StreamChatGenerics> & {\n quoted_message?: MessageResponseBase<StreamChatGenerics>;\n};\n\nexport type MessageResponseBase<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MessageBase<StreamChatGenerics> & {\n type: MessageLabel;\n args?: string;\n before_message_send_failed?: boolean;\n channel?: ChannelResponse<StreamChatGenerics>;\n cid?: string;\n command?: string;\n command_info?: { name?: string };\n created_at?: string;\n deleted_at?: string;\n deleted_reply_count?: number;\n i18n?: RequireAtLeastOne<Record<`${TranslationLanguages}_text`, string>> & {\n language: TranslationLanguages;\n };\n latest_reactions?: ReactionResponse<StreamChatGenerics>[];\n mentioned_users?: UserResponse<StreamChatGenerics>[];\n message_text_updated_at?: string;\n moderation?: ModerationResponse; // present only with Moderation v2\n moderation_details?: ModerationDetailsResponse; // present only with Moderation v1\n own_reactions?: ReactionResponse<StreamChatGenerics>[] | null;\n pin_expires?: string | null;\n pinned_at?: string | null;\n pinned_by?: UserResponse<StreamChatGenerics> | null;\n poll?: PollResponse<StreamChatGenerics>;\n reaction_counts?: { [key: string]: number } | null;\n reaction_groups?: { [key: string]: ReactionGroupResponse } | null;\n reaction_scores?: { [key: string]: number } | null;\n reply_count?: number;\n shadowed?: boolean;\n status?: string;\n thread_participants?: UserResponse<StreamChatGenerics>[];\n updated_at?: string;\n};\n\nexport type ReactionGroupResponse = {\n count: number;\n sum_scores: number;\n first_reaction_at?: string;\n last_reaction_at?: string;\n};\n\nexport type ModerationDetailsResponse = {\n action: 'MESSAGE_RESPONSE_ACTION_BOUNCE' | (string & {});\n error_msg: string;\n harms: ModerationHarmResponse[];\n original_text: string;\n};\n\nexport type ModerationHarmResponse = {\n name: string;\n phrase_list_ids: number[];\n};\n\nexport type ModerationAction = 'bounce' | 'flag' | 'remove' | 'shadow';\n\nexport type ModerationResponse = {\n action: ModerationAction;\n original_text: string;\n};\n\nexport type MuteResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n created_at?: string;\n expires?: string;\n target?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n};\n\nexport type MuteUserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n mute?: MuteResponse<StreamChatGenerics>;\n mutes?: Array<Mute<StreamChatGenerics>>;\n own_user?: OwnUserResponse<StreamChatGenerics>;\n};\n\nexport type BlockUserAPIResponse = APIResponse & {\n blocked_at: string;\n blocked_by_user_id: string;\n blocked_user_id: string;\n};\n\nexport type GetBlockedUsersAPIResponse = APIResponse & {\n blocks: BlockedUserDetails[];\n};\nexport type BlockedUserDetails = APIResponse & {\n blocked_user: UserResponse;\n blocked_user_id: string;\n created_at: string;\n user: UserResponse;\n user_id: string;\n};\n\nexport type OwnUserBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel_mutes: ChannelMute<StreamChatGenerics>[];\n devices: Device<StreamChatGenerics>[];\n mutes: Mute<StreamChatGenerics>[];\n total_unread_count: number;\n unread_channels: number;\n unread_count: number;\n unread_threads: number;\n invisible?: boolean;\n privacy_settings?: PrivacySettings;\n roles?: string[];\n};\n\nexport type OwnUserResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = UserResponse<StreamChatGenerics> & OwnUserBase<StreamChatGenerics>;\n\nexport type PartialUpdateChannelAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n};\n\nexport type PermissionAPIResponse = APIResponse & {\n permission?: PermissionAPIObject;\n};\n\nexport type PermissionsAPIResponse = APIResponse & {\n permissions?: PermissionAPIObject[];\n};\n\nexport type ReactionAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n reaction: ReactionResponse<StreamChatGenerics>;\n};\n\nexport type ReactionResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Reaction<StreamChatGenerics> & {\n created_at: string;\n message_id: string;\n updated_at: string;\n};\n\nexport type ReadResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n last_read: string;\n user: UserResponse<StreamChatGenerics>;\n last_read_message_id?: string;\n unread_messages?: number;\n};\n\nexport type SearchAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n results: {\n message: MessageResponse<StreamChatGenerics>;\n }[];\n next?: string;\n previous?: string;\n results_warning?: SearchWarning | null;\n};\n\nexport type SearchWarning = {\n channel_search_cids: string[];\n channel_search_count: number;\n warning_code: number;\n warning_description: string;\n};\n\n// Thumb URL(thumb_url) is added considering video attachments as the backend will return the thumbnail in the response.\nexport type SendFileAPIResponse = APIResponse & { file: string; thumb_url?: string };\n\nexport type SendMessageAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n pending_message_metadata?: Record<string, string> | null;\n};\n\nexport type SyncResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n events: Event<StreamChatGenerics>[];\n inaccessible_cids?: string[];\n};\n\nexport type TruncateChannelAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n message?: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UpdateChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n message?: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UpdateChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id'> & {\n created_at: string;\n updated_at: string;\n };\n\nexport type UpdateCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n command: UpdateCommandOptions<StreamChatGenerics> &\n CreatedAtUpdatedAt & {\n name: CommandVariants<StreamChatGenerics>;\n };\n};\n\nexport type UpdateMessageAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UsersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n users: Array<UserResponse<StreamChatGenerics>>;\n};\n\nexport type UpdateUsersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n};\n\nexport type UserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = User<StreamChatGenerics> & {\n banned?: boolean;\n blocked_user_ids?: string[];\n created_at?: string;\n deactivated_at?: string;\n deleted_at?: string;\n language?: TranslationLanguages | '';\n last_active?: string;\n online?: boolean;\n privacy_settings?: PrivacySettings;\n push_notifications?: PushNotificationSettings;\n revoke_tokens_issued_before?: string;\n shadow_banned?: boolean;\n updated_at?: string;\n};\n\nexport type PrivacySettings = {\n read_receipts?: {\n enabled?: boolean;\n };\n typing_indicators?: {\n enabled?: boolean;\n };\n};\n\nexport type PushNotificationSettings = {\n disabled?: boolean;\n disabled_until?: string | null;\n};\n\n/**\n * Option Types\n */\n\nexport type MessageFlagsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type FlagsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type FlagReportsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type ReviewFlagReportOptions = {\n review_details?: Object;\n user_id?: string;\n};\n\nexport type BannedUsersPaginationOptions = Omit<PaginationOptions, 'id_gt' | 'id_gte' | 'id_lt' | 'id_lte'> & {\n exclude_expired_bans?: boolean;\n};\n\nexport type BanUserOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = UnBanUserOptions & {\n banned_by?: UserResponse<StreamChatGenerics>;\n banned_by_id?: string;\n ip_ban?: boolean;\n reason?: string;\n timeout?: number;\n};\n\nexport type ChannelOptions = {\n limit?: number;\n member_limit?: number;\n message_limit?: number;\n offset?: number;\n presence?: boolean;\n state?: boolean;\n user_id?: string;\n watch?: boolean;\n};\n\nexport type ChannelQueryOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n data?: ChannelResponse<StreamChatGenerics>;\n hide_for_creator?: boolean;\n members?: PaginationOptions;\n messages?: MessagePaginationOptions;\n presence?: boolean;\n state?: boolean;\n watch?: boolean;\n watchers?: PaginationOptions;\n};\n\nexport type ChannelStateOptions = {\n offlineMode?: boolean;\n skipInitialization?: string[];\n};\n\nexport type CreateChannelOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist?: string;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n client_id?: string;\n commands?: CommandVariants<StreamChatGenerics>[];\n connect_events?: boolean;\n connection_id?: string;\n custom_events?: boolean;\n grants?: Record<string, string[]>;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n permissions?: PermissionObject[];\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n reminders?: boolean;\n replies?: boolean;\n search?: boolean;\n skip_last_msg_update_for_system_msgs?: boolean;\n typing_events?: boolean;\n uploads?: boolean;\n url_enrichment?: boolean;\n};\n\nexport type CreateCommandOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n description: string;\n name: CommandVariants<StreamChatGenerics>;\n args?: string;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type CustomPermissionOptions = {\n action: string;\n condition: object;\n id: string;\n name: string;\n description?: string;\n owner?: boolean;\n same_team?: boolean;\n};\n\nexport type DeactivateUsersOptions = {\n created_by_id?: string;\n mark_messages_deleted?: boolean;\n};\n\nexport type NewMemberPayload<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & Pick<ChannelMemberResponse<StreamChatGenerics>, 'user_id' | 'channel_role'>;\n\n// TODO: rename to UpdateChannelOptions in the next major update and use it in channel._update and/or channel.update\nexport type InviteOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n accept_invite?: boolean;\n add_members?: string[];\n add_moderators?: string[];\n client_id?: string;\n connection_id?: string;\n data?: Omit<ChannelResponse<StreamChatGenerics>, 'id' | 'cid'>;\n demote_moderators?: string[];\n invites?: string[];\n message?: MessageResponse<StreamChatGenerics>;\n reject_invite?: boolean;\n remove_members?: string[];\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\n/** @deprecated use MarkChannelsReadOptions instead */\nexport type MarkAllReadOptions<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MarkChannelsReadOptions<StreamChatGenerics>;\n\nexport type MarkChannelsReadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n read_by_channel?: Record<string, string>;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MarkReadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n thread_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MarkUnreadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n message_id?: string;\n thread_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MuteUserOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n id?: string;\n reason?: string;\n target_user_id?: string;\n timeout?: number;\n type?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PaginationOptions = {\n created_at_after?: string | Date;\n created_at_after_or_equal?: string | Date;\n created_at_before?: string | Date;\n created_at_before_or_equal?: string | Date;\n id_gt?: string;\n id_gte?: string;\n id_lt?: string;\n id_lte?: string;\n limit?: number;\n offset?: number; // should be avoided with channel.query()\n};\n\nexport type MessagePaginationOptions = PaginationOptions & {\n created_at_around?: string | Date;\n id_around?: string;\n};\n\nexport type PinnedMessagePaginationOptions = {\n id_around?: string;\n id_gt?: string;\n id_gte?: string;\n id_lt?: string;\n id_lte?: string;\n limit?: number;\n offset?: number;\n pinned_at_after?: string | Date;\n pinned_at_after_or_equal?: string | Date;\n pinned_at_around?: string | Date;\n pinned_at_before?: string | Date;\n pinned_at_before_or_equal?: string | Date;\n};\n\nexport type QueryMembersOptions = {\n // Pagination option: select members created after the date (RFC399)\n created_at_after?: string;\n // Pagination option: select members created after or equal the date (RFC399)\n created_at_after_or_equal?: string;\n // Pagination option: select members created before the date (RFC399)\n created_at_before?: string;\n // Pagination option: select members created before or equal the date (RFC399)\n created_at_before_or_equal?: string;\n // Number of members to return, default 100\n limit?: number;\n // Offset (max is 1000)\n offset?: number;\n // \tPagination option: excludes members with ID less or equal the value\n user_id_gt?: string;\n // Pagination option: excludes members with ID less than the value\n user_id_gte?: string;\n // Pagination option: excludes members with ID greater or equal the value\n user_id_lt?: string;\n // \tPagination option: excludes members with ID greater than the value\n user_id_lte?: string;\n};\n\nexport type ReactivateUserOptions = {\n created_by_id?: string;\n name?: string;\n restore_messages?: boolean;\n};\n\nexport type ReactivateUsersOptions = {\n created_by_id?: string;\n restore_messages?: boolean;\n};\n\nexport type SearchOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n limit?: number;\n next?: string;\n offset?: number;\n sort?: SearchMessageSort<StreamChatGenerics>;\n};\n\nexport type StreamChatOptions = AxiosRequestConfig & {\n /**\n * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.\n */\n allowServerSideConnect?: boolean;\n axiosRequestConfig?: AxiosRequestConfig;\n /**\n * Base url to use for API\n * such as https://chat-proxy-dublin.stream-io-api.com\n */\n baseURL?: string;\n browser?: boolean;\n device?: BaseDeviceFields;\n enableInsights?: boolean;\n /** experimental feature, please contact support if you want this feature enabled for you */\n enableWSFallback?: boolean;\n logger?: Logger;\n /**\n * When true, user will be persisted on client. Otherwise if `connectUser` call fails, then you need to\n * call `connectUser` again to retry.\n * This is mainly useful for chat application working in offline mode, where you will need client.user to\n * persist even if connectUser call fails.\n */\n persistUserOnConnectionFailure?: boolean;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n warmUp?: boolean;\n // Set the instance of StableWSConnection on chat client. Its purely for testing purpose and should\n // not be used in production apps.\n wsConnection?: StableWSConnection;\n};\n\nexport type SyncOptions = {\n /**\n * This will behave as queryChannels option.\n */\n watch?: boolean;\n /**\n * Return channels from request that user does not have access to in a separate\n * field in the response called 'inaccessible_cids' instead of\n * adding them as 'notification.removed_from_channel' events.\n */\n with_inaccessible_cids?: boolean;\n};\n\nexport type UnBanUserOptions = {\n client_id?: string;\n connection_id?: string;\n id?: string;\n shadow?: boolean;\n target_user_id?: string;\n type?: string;\n};\n\n// TODO: rename to UpdateChannelTypeOptions in the next major update\nexport type UpdateChannelOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n CreateChannelOptions<StreamChatGenerics>,\n 'name'\n> & {\n created_at?: string;\n updated_at?: string;\n};\n\nexport type UpdateCommandOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n description: string;\n args?: string;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type UserOptions = {\n include_deactivated_users?: boolean;\n limit?: number;\n offset?: number;\n presence?: boolean;\n};\n\n/**\n * Event Types\n */\n\nexport type ConnectionChangeEvent = {\n type: EventTypes;\n online?: boolean;\n};\n\nexport type Event<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = StreamChatGenerics['eventType'] & {\n type: EventTypes;\n channel?: ChannelResponse<StreamChatGenerics>;\n channel_id?: string;\n channel_type?: string;\n cid?: string;\n clear_history?: boolean;\n connection_id?: string;\n // event creation timestamp, format Date ISO string\n created_at?: string;\n // id of the message that was marked as unread - all the following messages are considered unread. (notification.mark_unread)\n first_unread_message_id?: string;\n hard_delete?: boolean;\n // creation date of a message with last_read_message_id, formatted as Date ISO string\n last_read_at?: string;\n last_read_message_id?: string;\n mark_messages_deleted?: boolean;\n me?: OwnUserResponse<StreamChatGenerics>;\n member?: ChannelMemberResponse<StreamChatGenerics>;\n message?: MessageResponse<StreamChatGenerics>;\n mode?: string;\n online?: boolean;\n parent_id?: string;\n poll?: PollResponse<StreamChatGenerics>;\n poll_vote?: PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>;\n queriedChannels?: {\n channels: ChannelAPIResponse<StreamChatGenerics>[];\n isLatestMessageSet?: boolean;\n };\n reaction?: ReactionResponse<StreamChatGenerics>;\n received_at?: string | Date;\n team?: string;\n thread?: ThreadResponse<StreamChatGenerics>;\n // @deprecated number of all unread messages across all current user's unread channels, equals unread_count\n total_unread_count?: number;\n // number of all current user's channels with at least one unread message including the channel in this event\n unread_channels?: number;\n // number of all unread messages across all current user's unread channels\n unread_count?: number;\n // number of unread messages in the channel from this event (notification.mark_unread)\n unread_messages?: number;\n unread_thread_messages?: number;\n unread_threads?: number;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n watcher_count?: number;\n};\n\nexport type UserCustomEvent<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['eventType'] & {\n type: string;\n};\n\nexport type EventHandler<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = (\n event: Event<StreamChatGenerics>,\n) => void;\n\nexport type EventTypes = 'all' | keyof typeof EVENT_MAP;\n\n/**\n * Filter Types\n */\n\nexport type AscDesc = 1 | -1;\n\nexport type MessageFlagsFiltersOptions = {\n channel_cid?: string;\n is_reviewed?: boolean;\n team?: string;\n user_id?: string;\n};\n\nexport type MessageFlagsFilters = QueryFilters<\n {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['channel_cid']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['team']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['user_id']>;\n } & {\n [Key in keyof Omit<MessageFlagsFiltersOptions, 'channel_cid' | 'user_id' | 'is_reviewed'>]:\n | RequireOnlyOne<QueryFilter<MessageFlagsFiltersOptions[Key]>>\n | PrimitiveFilter<MessageFlagsFiltersOptions[Key]>;\n }\n>;\n\nexport type FlagsFiltersOptions = {\n channel_cid?: string;\n message_id?: string;\n message_user_id?: string;\n reporter_id?: string;\n team?: string;\n user_id?: string;\n};\n\nexport type FlagsFilters = QueryFilters<\n {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['user_id']>;\n } & {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['message_id']>;\n } & {\n message_user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['message_user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['message_user_id']>;\n } & {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['channel_cid']>;\n } & {\n reporter_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['reporter_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['reporter_id']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['team']>;\n }\n>;\n\nexport type FlagReportsFiltersOptions = {\n channel_cid?: string;\n is_reviewed?: boolean;\n message_id?: string;\n message_user_id?: string;\n report_id?: string;\n review_result?: string;\n reviewed_by?: string;\n team?: string;\n user_id?: string;\n};\n\nexport type FlagReportsFilters = QueryFilters<\n {\n report_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['report_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['report_id']>;\n } & {\n review_result?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['review_result']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['review_result']>;\n } & {\n reviewed_by?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['reviewed_by']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['reviewed_by']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['user_id']>;\n } & {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['message_id']>;\n } & {\n message_user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['message_user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['message_user_id']>;\n } & {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['channel_cid']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['team']>;\n } & {\n [Key in keyof Omit<\n FlagReportsFiltersOptions,\n 'report_id' | 'user_id' | 'message_id' | 'review_result' | 'reviewed_by'\n >]: RequireOnlyOne<QueryFilter<FlagReportsFiltersOptions[Key]>> | PrimitiveFilter<FlagReportsFiltersOptions[Key]>;\n }\n>;\n\nexport type BannedUsersFilterOptions = {\n banned_by_id?: string;\n channel_cid?: string;\n created_at?: string;\n reason?: string;\n user_id?: string;\n};\n\nexport type BannedUsersFilters = QueryFilters<\n {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<BannedUsersFilterOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<BannedUsersFilterOptions['channel_cid']>;\n } & {\n reason?:\n | RequireOnlyOne<\n {\n $autocomplete?: BannedUsersFilterOptions['reason'];\n } & QueryFilter<BannedUsersFilterOptions['reason']>\n >\n | PrimitiveFilter<BannedUsersFilterOptions['reason']>;\n } & {\n [Key in keyof Omit<BannedUsersFilterOptions, 'channel_cid' | 'reason'>]:\n | RequireOnlyOne<QueryFilter<BannedUsersFilterOptions[Key]>>\n | PrimitiveFilter<BannedUsersFilterOptions[Key]>;\n }\n>;\n\nexport type ReactionFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<ReactionResponse<StreamChatGenerics>['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReactionResponse<StreamChatGenerics>['user_id']>;\n } & {\n type?:\n | RequireOnlyOne<Pick<QueryFilter<ReactionResponse<StreamChatGenerics>['type']>, '$eq'>>\n | PrimitiveFilter<ReactionResponse<StreamChatGenerics>['type']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n }\n>;\n\nexport type ChannelFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['channelType']> & {\n members?:\n | RequireOnlyOne<Pick<QueryFilter<string>, '$in' | '$nin'>>\n | RequireOnlyOne<Pick<QueryFilter<string[]>, '$eq'>>\n | PrimitiveFilter<string[]>;\n } & {\n name?:\n | RequireOnlyOne<\n {\n $autocomplete?: ChannelResponse<StreamChatGenerics>['name'];\n } & QueryFilter<ChannelResponse<StreamChatGenerics>['name']>\n >\n | PrimitiveFilter<ChannelResponse<StreamChatGenerics>['name']>;\n } & {\n [Key in keyof Omit<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'name' | 'members'\n >]:\n | RequireOnlyOne<\n QueryFilter<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >\n >\n | PrimitiveFilter<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >;\n } & {\n archived?: boolean;\n pinned?: boolean;\n }\n>;\n\nexport type QueryPollsParams = {\n filter?: QueryPollsFilters;\n options?: QueryPollsOptions;\n sort?: PollSort;\n};\n\nexport type QueryPollsOptions = Pager;\n\nexport type VotesFiltersOptions = {\n is_answer?: boolean;\n option_id?: string;\n user_id?: string;\n};\n\nexport type QueryVotesOptions = Pager;\n\nexport type QueryPollsFilters = QueryFilters<\n {\n id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['user_id']>;\n } & {\n is_closed?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['is_closed']>, '$eq'>>\n | PrimitiveFilter<PollResponse['is_closed']>;\n } & {\n max_votes_allowed?:\n | RequireOnlyOne<\n Pick<QueryFilter<PollResponse['max_votes_allowed']>, '$eq' | '$ne' | '$gt' | '$lt' | '$gte' | '$lte'>\n >\n | PrimitiveFilter<PollResponse['max_votes_allowed']>;\n } & {\n allow_answers?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['allow_answers']>, '$eq'>>\n | PrimitiveFilter<PollResponse['allow_answers']>;\n } & {\n allow_user_suggested_options?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['allow_user_suggested_options']>, '$eq'>>\n | PrimitiveFilter<PollResponse['allow_user_suggested_options']>;\n } & {\n voting_visibility?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['voting_visibility']>, '$eq'>>\n | PrimitiveFilter<PollResponse['voting_visibility']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n } & {\n created_by_id?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['created_by_id']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['updated_at']>;\n } & {\n name?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['name']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['name']>;\n }\n>;\n\nexport type QueryVotesFilters = QueryFilters<\n {\n id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>;\n } & {\n option_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['option_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['option_id']>;\n } & {\n is_answer?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['is_answer']>, '$eq'>>\n | PrimitiveFilter<VotesFiltersOptions['is_answer']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['user_id']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n } & {\n created_by_id?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['created_by_id']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['updated_at']>;\n }\n>;\n\nexport type ContainsOperator<CustomType = {}> = {\n [Key in keyof CustomType]?: CustomType[Key] extends (infer ContainType)[]\n ?\n | RequireOnlyOne<\n {\n $contains?: ContainType extends object\n ? PrimitiveFilter<RequireAtLeastOne<ContainType>>\n : PrimitiveFilter<ContainType>;\n } & QueryFilter<PrimitiveFilter<ContainType>[]>\n >\n | PrimitiveFilter<PrimitiveFilter<ContainType>[]>\n : RequireOnlyOne<QueryFilter<CustomType[Key]>> | PrimitiveFilter<CustomType[Key]>;\n};\n\nexport type MessageFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['messageType']> & {\n text?:\n | RequireOnlyOne<\n {\n $autocomplete?: MessageResponse<StreamChatGenerics>['text'];\n $q?: MessageResponse<StreamChatGenerics>['text'];\n } & QueryFilter<MessageResponse<StreamChatGenerics>['text']>\n >\n | PrimitiveFilter<MessageResponse<StreamChatGenerics>['text']>;\n } & {\n [Key in keyof Omit<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'text'\n >]?:\n | RequireOnlyOne<\n QueryFilter<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >\n >\n | PrimitiveFilter<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >;\n }\n>;\n\nexport type PrimitiveFilter<ObjectType> = ObjectType | null;\n\nexport type QueryFilter<ObjectType = string> = NonNullable<ObjectType> extends string | number | boolean\n ? {\n $eq?: PrimitiveFilter<ObjectType>;\n $exists?: boolean;\n $gt?: PrimitiveFilter<ObjectType>;\n $gte?: PrimitiveFilter<ObjectType>;\n $in?: PrimitiveFilter<ObjectType>[];\n $lt?: PrimitiveFilter<ObjectType>;\n $lte?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $ne?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $nin?: PrimitiveFilter<ObjectType>[];\n }\n : {\n $eq?: PrimitiveFilter<ObjectType>;\n $exists?: boolean;\n $in?: PrimitiveFilter<ObjectType>[];\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $ne?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $nin?: PrimitiveFilter<ObjectType>[];\n };\n\nexport type QueryFilters<Operators = {}> = {\n [Key in keyof Operators]?: Operators[Key];\n} &\n QueryLogicalOperators<Operators>;\n\nexport type QueryLogicalOperators<Operators> = {\n $and?: ArrayOneOrMore<QueryFilters<Operators>>;\n $nor?: ArrayOneOrMore<QueryFilters<Operators>>;\n $or?: ArrayTwoOrMore<QueryFilters<Operators>>;\n};\n\nexport type UserFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['userType']> & {\n id?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['id'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['id']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['id']>;\n name?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['name'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['name']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['name']>;\n notifications_muted?:\n | RequireOnlyOne<{\n $eq?: PrimitiveFilter<UserResponse<StreamChatGenerics>['notifications_muted']>;\n }>\n | boolean;\n teams?:\n | RequireOnlyOne<{\n $contains?: PrimitiveFilter<string>;\n $eq?: PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n $in?: PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n }>\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n username?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['username'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['username']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['username']>;\n } & {\n [Key in keyof Omit<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>,\n 'id' | 'name' | 'teams' | 'username'\n >]?:\n | RequireOnlyOne<\n QueryFilter<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>[Key]\n >\n >\n | PrimitiveFilter<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>[Key]\n >;\n }\n>;\n\nexport type InviteStatus = 'pending' | 'accepted' | 'rejected';\n\n// https://getstream.io/chat/docs/react/channel_member/#update-channel-members\nexport type MemberFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n {\n banned?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['banned'] }\n | ChannelMemberResponse<StreamChatGenerics>['banned'];\n channel_role?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['channel_role'] }\n | ChannelMemberResponse<StreamChatGenerics>['channel_role'];\n cid?: { $eq?: ChannelResponse<StreamChatGenerics>['cid'] } | ChannelResponse<StreamChatGenerics>['cid'];\n created_at?:\n | {\n $eq?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $gt?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $gte?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $lt?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $lte?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n }\n | ChannelMemberResponse<StreamChatGenerics>['created_at'];\n id?:\n | RequireOnlyOne<{\n $eq?: UserResponse<StreamChatGenerics>['id'];\n $in?: UserResponse<StreamChatGenerics>['id'][];\n }>\n | UserResponse<StreamChatGenerics>['id'];\n invite?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['status'] }\n | ChannelMemberResponse<StreamChatGenerics>['status'];\n joined?: { $eq?: boolean } | boolean;\n last_active?:\n | {\n $eq?: UserResponse<StreamChatGenerics>['last_active'];\n $gt?: UserResponse<StreamChatGenerics>['last_active'];\n $gte?: UserResponse<StreamChatGenerics>['last_active'];\n $lt?: UserResponse<StreamChatGenerics>['last_active'];\n $lte?: UserResponse<StreamChatGenerics>['last_active'];\n }\n | UserResponse<StreamChatGenerics>['last_active'];\n name?:\n | RequireOnlyOne<{\n $autocomplete?: ChannelMemberResponse<StreamChatGenerics>['name'];\n $eq?: ChannelMemberResponse<StreamChatGenerics>['name'];\n $in?: ChannelMemberResponse<StreamChatGenerics>['name'][];\n $q?: ChannelMemberResponse<StreamChatGenerics>['name'];\n }>\n | PrimitiveFilter<ChannelMemberResponse<StreamChatGenerics>['name']>;\n updated_at?:\n | {\n $eq?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $gt?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $gte?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $lt?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $lte?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n }\n | ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n 'user.email'?:\n | RequireOnlyOne<{\n $autocomplete?: string;\n $eq?: string;\n $in?: string;\n }>\n | string;\n user_id?:\n | RequireOnlyOne<{\n $eq?: ChannelMemberResponse<StreamChatGenerics>['user_id'];\n $in?: ChannelMemberResponse<StreamChatGenerics>['user_id'][];\n }>\n | PrimitiveFilter<ChannelMemberResponse<StreamChatGenerics>['id']>;\n } & {\n [Key in keyof ContainsOperator<StreamChatGenerics['memberType']>]?:\n | RequireOnlyOne<QueryFilter<ContainsOperator<StreamChatGenerics['memberType']>[Key]>>\n | PrimitiveFilter<ContainsOperator<StreamChatGenerics['memberType']>[Key]>;\n }\n>;\n\n/**\n * Sort Types\n */\n\nexport type BannedUsersSort = BannedUsersSortBase | Array<BannedUsersSortBase>;\n\nexport type BannedUsersSortBase = { created_at?: AscDesc };\n\nexport type ReactionSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | ReactionSortBase<StreamChatGenerics>\n | Array<ReactionSortBase<StreamChatGenerics>>;\n\nexport type ReactionSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['reactionType']\n> & {\n created_at?: AscDesc;\n};\n\nexport type ChannelSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | ChannelSortBase<StreamChatGenerics>\n | Array<ChannelSortBase<StreamChatGenerics>>\n | { pinned_at: AscDesc };\n\nexport type ChannelSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['channelType']\n> & {\n created_at?: AscDesc;\n has_unread?: AscDesc;\n last_message_at?: AscDesc;\n last_updated?: AscDesc;\n member_count?: AscDesc;\n unread_count?: AscDesc;\n updated_at?: AscDesc;\n};\n\nexport type PinnedMessagesSort = PinnedMessagesSortBase | Array<PinnedMessagesSortBase>;\nexport type PinnedMessagesSortBase = { pinned_at?: AscDesc };\n\nexport type Sort<T> = {\n [P in keyof T]?: AscDesc;\n};\n\nexport type UserSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | Sort<UserResponse<StreamChatGenerics>>\n | Array<Sort<UserResponse<StreamChatGenerics>>>;\n\nexport type MemberSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | Sort<Pick<UserResponse<StreamChatGenerics>, 'id' | 'created_at' | 'last_active' | 'name' | 'updated_at'>>\n | Array<Sort<Pick<UserResponse<StreamChatGenerics>, 'id' | 'created_at' | 'last_active' | 'name' | 'updated_at'>>>;\n\nexport type SearchMessageSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['messageType']\n> & {\n attachments?: AscDesc;\n 'attachments.type'?: AscDesc;\n created_at?: AscDesc;\n id?: AscDesc;\n 'mentioned_users.id'?: AscDesc;\n parent_id?: AscDesc;\n pinned?: AscDesc;\n relevance?: AscDesc;\n reply_count?: AscDesc;\n text?: AscDesc;\n type?: AscDesc;\n updated_at?: AscDesc;\n 'user.id'?: AscDesc;\n};\n\nexport type SearchMessageSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | SearchMessageSortBase<StreamChatGenerics>\n | Array<SearchMessageSortBase<StreamChatGenerics>>;\n\nexport type QuerySort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | BannedUsersSort\n | ChannelSort<StreamChatGenerics>\n | SearchMessageSort<StreamChatGenerics>\n | UserSort<StreamChatGenerics>;\n\nexport type PollSort = PollSortBase | Array<PollSortBase>;\n\nexport type PollSortBase = {\n created_at?: AscDesc;\n id?: AscDesc;\n is_closed?: AscDesc;\n name?: AscDesc;\n updated_at?: AscDesc;\n};\n\nexport type VoteSort = VoteSortBase | Array<VoteSortBase>;\n\nexport type VoteSortBase = {\n created_at?: AscDesc;\n id?: AscDesc;\n is_closed?: AscDesc;\n name?: AscDesc;\n updated_at?: AscDesc;\n};\n\n/**\n * Base Types\n */\n\nexport type Action = {\n name?: string;\n style?: string;\n text?: string;\n type?: string;\n value?: string;\n};\n\nexport type AnonUserType = {};\n\nexport type APNConfig = {\n auth_key?: string;\n auth_type?: string;\n bundle_id?: string;\n development?: boolean;\n enabled?: boolean;\n host?: string;\n key_id?: string;\n notification_template?: string;\n p12_cert?: string;\n team_id?: string;\n};\n\nexport type AgoraOptions = {\n app_certificate: string;\n app_id: string;\n role_map?: Record<string, string>;\n};\n\nexport type HMSOptions = {\n app_access_key: string;\n app_secret: string;\n default_role: string;\n default_room_template: string;\n default_region?: string;\n role_map?: Record<string, string>;\n};\n\nexport type AsyncModerationOptions = {\n callback?: {\n mode?: 'CALLBACK_MODE_NONE' | 'CALLBACK_MODE_REST' | 'CALLBACK_MODE_TWIRP';\n server_url?: string;\n };\n timeout_ms?: number;\n};\n\nexport type AppSettings = {\n agora_options?: AgoraOptions | null;\n allowed_flag_reasons?: string[];\n apn_config?: {\n auth_key?: string;\n auth_type?: string;\n bundle_id?: string;\n development?: boolean;\n host?: string;\n key_id?: string;\n notification_template?: string;\n p12_cert?: string;\n team_id?: string;\n };\n async_moderation_config?: AsyncModerationOptions;\n async_url_enrich_enabled?: boolean;\n auto_translation_enabled?: boolean;\n before_message_send_hook_url?: string;\n cdn_expiration_seconds?: number;\n custom_action_handler_url?: string;\n disable_auth_checks?: boolean;\n disable_permissions_checks?: boolean;\n enforce_unique_usernames?: 'no' | 'app' | 'team';\n // all possible file mime types are https://www.iana.org/assignments/media-types/media-types.xhtml\n file_upload_config?: FileUploadConfig;\n firebase_config?: {\n apn_template?: string;\n credentials_json?: string;\n data_template?: string;\n notification_template?: string;\n server_key?: string;\n };\n grants?: Record<string, string[]>;\n hms_options?: HMSOptions | null;\n huawei_config?: {\n id: string;\n secret: string;\n };\n image_moderation_enabled?: boolean;\n image_upload_config?: FileUploadConfig;\n migrate_permissions_to_v2?: boolean;\n multi_tenant_enabled?: boolean;\n permission_version?: 'v1' | 'v2';\n push_config?: {\n offline_only?: boolean;\n version?: string;\n };\n reminders_interval?: number;\n revoke_tokens_issued_before?: string | null;\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n video_provider?: string;\n webhook_events?: Array<string> | null;\n webhook_url?: string;\n xiaomi_config?: {\n package_name: string;\n secret: string;\n };\n};\n\nexport type Attachment<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['attachmentType'] & {\n actions?: Action[];\n asset_url?: string;\n author_icon?: string;\n author_link?: string;\n author_name?: string;\n color?: string;\n duration?: number;\n fallback?: string;\n fields?: Field[];\n file_size?: number | string;\n footer?: string;\n footer_icon?: string;\n giphy?: GiphyData;\n image_url?: string;\n mime_type?: string;\n og_scrape_url?: string;\n original_height?: number;\n original_width?: number;\n pretext?: string;\n text?: string;\n thumb_url?: string;\n title?: string;\n title_link?: string;\n type?: string;\n waveform_data?: Array<number>;\n};\n\nexport type OGAttachment = {\n og_scrape_url: string;\n asset_url?: string; // og:video | og:audio\n author_link?: string; // og:site\n author_name?: string; // og:site_name\n image_url?: string; // og:image\n text?: string; // og:description\n thumb_url?: string; // og:image\n title?: string; // og:title\n title_link?: string; // og:url\n type?: string | 'video' | 'audio' | 'image';\n};\n\nexport type BlockList = {\n name: string;\n words: string[];\n type?: string;\n validate?: boolean;\n};\n\nexport type ChannelConfig<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = ChannelConfigFields &\n CreatedAtUpdatedAt & {\n commands?: CommandVariants<StreamChatGenerics>[];\n };\n\nexport type ChannelConfigAutomod = '' | 'AI' | 'disabled' | 'simple';\n\nexport type ChannelConfigAutomodBehavior = '' | 'block' | 'flag';\n\nexport type ChannelConfigAutomodThresholds = null | {\n explicit?: { block?: number; flag?: number };\n spam?: { block?: number; flag?: number };\n toxic?: { block?: number; flag?: number };\n};\n\nexport type ChannelConfigFields = {\n reminders: boolean;\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n connect_events?: boolean;\n custom_events?: boolean;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n replies?: boolean;\n search?: boolean;\n typing_events?: boolean;\n uploads?: boolean;\n url_enrichment?: boolean;\n};\n\nexport type ChannelConfigWithInfo<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ChannelConfigFields &\n CreatedAtUpdatedAt & {\n commands?: CommandResponse<StreamChatGenerics>[];\n };\n\nexport type ChannelData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['channelType'] & {\n blocked?: boolean;\n members?: string[] | Array<NewMemberPayload<StreamChatGenerics>>;\n name?: string;\n};\n\n/**\n * @deprecated Use ChannelMemberResponse instead\n */\nexport type ChannelMembership<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ChannelMemberResponse<StreamChatGenerics>;\n\nexport type ChannelMute<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n channel?: ChannelResponse<StreamChatGenerics>;\n created_at?: string;\n expires?: string;\n updated_at?: string;\n};\n\nexport type ChannelRole = {\n custom?: boolean;\n name?: string;\n owner?: boolean;\n resource?: string;\n same_team?: boolean;\n};\n\nexport type CheckPushInput<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n apn_template?: string;\n client_id?: string;\n connection_id?: string;\n firebase_data_template?: string;\n firebase_template?: string;\n message_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PushProvider = 'apn' | 'firebase' | 'huawei' | 'xiaomi';\n\nexport type PushProviderConfig = PushProviderCommon &\n PushProviderID &\n PushProviderAPN &\n PushProviderFirebase &\n PushProviderHuawei &\n PushProviderXiaomi;\n\nexport type PushProviderID = {\n name: string;\n type: PushProvider;\n};\n\nexport type PushProviderCommon = {\n created_at: string;\n updated_at: string;\n description?: string;\n disabled_at?: string;\n disabled_reason?: string;\n};\n\nexport type PushProviderAPN = {\n apn_auth_key?: string;\n apn_auth_type?: 'token' | 'certificate';\n apn_development?: boolean;\n apn_host?: string;\n apn_key_id?: string;\n apn_notification_template?: string;\n apn_p12_cert?: string;\n apn_team_id?: string;\n apn_topic?: string;\n};\n\nexport type PushProviderFirebase = {\n firebase_apn_template?: string;\n firebase_credentials?: string;\n firebase_data_template?: string;\n firebase_notification_template?: string;\n firebase_server_key?: string;\n};\n\nexport type PushProviderHuawei = {\n huawei_app_id?: string;\n huawei_app_secret?: string;\n};\n\nexport type PushProviderXiaomi = {\n xiaomi_package_name?: string;\n xiaomi_secret?: string;\n};\n\nexport type CommandVariants<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | 'all'\n | 'ban'\n | 'fun_set'\n | 'giphy'\n | 'moderation_set'\n | 'mute'\n | 'unban'\n | 'unmute'\n | StreamChatGenerics['commandType'];\n\nexport type Configs<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n ChannelConfigWithInfo<StreamChatGenerics> | undefined\n>;\n\nexport type ConnectionOpen<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n connection_id: string;\n cid?: string;\n created_at?: string;\n me?: OwnUserResponse<StreamChatGenerics>;\n type?: string;\n};\n\nexport type CreatedAtUpdatedAt = {\n created_at: string;\n updated_at: string;\n};\n\nexport type Device<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = DeviceFields & {\n provider?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type BaseDeviceFields = {\n id: string;\n push_provider: PushProvider;\n push_provider_name?: string;\n};\n\nexport type DeviceFields = BaseDeviceFields & {\n created_at: string;\n disabled?: boolean;\n disabled_reason?: string;\n};\n\nexport type EndpointName =\n | 'Connect'\n | 'LongPoll'\n | 'DeleteFile'\n | 'DeleteImage'\n | 'DeleteMessage'\n | 'DeleteUser'\n | 'DeleteUsers'\n | 'DeactivateUser'\n | 'ExportUser'\n | 'DeleteReaction'\n | 'UpdateChannel'\n | 'UpdateChannelPartial'\n | 'UpdateMessage'\n | 'UpdateMessagePartial'\n | 'GetMessage'\n | 'GetManyMessages'\n | 'UpdateUsers'\n | 'UpdateUsersPartial'\n | 'CreateGuest'\n | 'GetOrCreateChannel'\n | 'StopWatchingChannel'\n | 'QueryChannels'\n | 'Search'\n | 'QueryUsers'\n | 'QueryMembers'\n | 'QueryBannedUsers'\n | 'QueryFlags'\n | 'QueryMessageFlags'\n | 'GetReactions'\n | 'GetReplies'\n | 'GetPinnedMessages'\n | 'Ban'\n | 'Unban'\n | 'MuteUser'\n | 'MuteChannel'\n | 'UnmuteChannel'\n | 'UnmuteUser'\n | 'RunMessageAction'\n | 'SendEvent'\n | 'SendUserCustomEvent'\n | 'MarkRead'\n | 'MarkChannelsRead'\n | 'SendMessage'\n | 'ImportChannelMessages'\n | 'UploadFile'\n | 'UploadImage'\n | 'UpdateApp'\n | 'GetApp'\n | 'CreateDevice'\n | 'DeleteDevice'\n | 'SendReaction'\n | 'Flag'\n | 'Unflag'\n | 'Unblock'\n | 'QueryFlagReports'\n | 'FlagReportReview'\n | 'CreateChannelType'\n | 'DeleteChannel'\n | 'DeleteChannels'\n | 'DeleteChannelType'\n | 'GetChannelType'\n | 'ListChannelTypes'\n | 'ListDevices'\n | 'TruncateChannel'\n | 'UpdateChannelType'\n | 'CheckPush'\n | 'PrivateSubmitModeration'\n | 'ReactivateUser'\n | 'HideChannel'\n | 'ShowChannel'\n | 'CreatePermission'\n | 'UpdatePermission'\n | 'GetPermission'\n | 'DeletePermission'\n | 'ListPermissions'\n | 'CreateRole'\n | 'DeleteRole'\n | 'ListRoles'\n | 'ListCustomRoles'\n | 'Sync'\n | 'TranslateMessage'\n | 'CreateCommand'\n | 'GetCommand'\n | 'UpdateCommand'\n | 'DeleteCommand'\n | 'ListCommands'\n | 'CreateBlockList'\n | 'UpdateBlockList'\n | 'GetBlockList'\n | 'ListBlockLists'\n | 'DeleteBlockList'\n | 'ExportChannels'\n | 'GetExportChannelsStatus'\n | 'CheckSQS'\n | 'GetRateLimits'\n | 'CreateSegment'\n | 'GetSegment'\n | 'QuerySegments'\n | 'UpdateSegment'\n | 'DeleteSegment'\n | 'CreateCampaign'\n | 'GetCampaign'\n | 'ListCampaigns'\n | 'UpdateCampaign'\n | 'DeleteCampaign'\n | 'ScheduleCampaign'\n | 'StopCampaign'\n | 'ResumeCampaign'\n | 'TestCampaign'\n | 'GetOG'\n | 'GetTask'\n | 'ExportUsers'\n | 'CreateImport'\n | 'CreateImportURL'\n | 'GetImport'\n | 'ListImports'\n | 'UpsertPushProvider'\n | 'DeletePushProvider'\n | 'ListPushProviders'\n | 'CreatePoll';\n\nexport type ExportChannelRequest = {\n id: string;\n type: string;\n cid?: string;\n messages_since?: Date;\n messages_until?: Date;\n};\n\nexport type ExportChannelOptions = {\n clear_deleted_message_text?: boolean;\n export_users?: boolean;\n include_soft_deleted_channels?: boolean;\n include_truncated_messages?: boolean;\n version?: string;\n};\n\nexport type ExportUsersRequest = {\n user_ids: string[];\n};\n\nexport type Field = {\n short?: boolean;\n title?: string;\n value?: string;\n};\n\nexport type FileUploadConfig = {\n allowed_file_extensions?: string[] | null;\n allowed_mime_types?: string[] | null;\n blocked_file_extensions?: string[] | null;\n blocked_mime_types?: string[] | null;\n size_limit?: number | null;\n};\n\nexport type FirebaseConfig = {\n apn_template?: string;\n credentials_json?: string;\n data_template?: string;\n enabled?: boolean;\n notification_template?: string;\n server_key?: string;\n};\n\ntype GiphyVersionInfo = {\n height: string;\n url: string;\n width: string;\n frames?: string;\n size?: string;\n};\n\ntype GiphyVersions =\n | 'original'\n | 'fixed_height'\n | 'fixed_height_still'\n | 'fixed_height_downsampled'\n | 'fixed_width'\n | 'fixed_width_still'\n | 'fixed_width_downsampled';\n\ntype GiphyData = {\n [key in GiphyVersions]: GiphyVersionInfo;\n};\n\nexport type HuaweiConfig = {\n enabled?: boolean;\n id?: string;\n secret?: string;\n};\n\nexport type XiaomiConfig = {\n enabled?: boolean;\n package_name?: string;\n secret?: string;\n};\n\nexport type LiteralStringForUnion = string & {};\n\nexport type LogLevel = 'info' | 'error' | 'warn';\n\nexport type Logger = (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => void;\n\nexport type Message<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n MessageBase<StreamChatGenerics>\n> & {\n mentioned_users?: string[];\n};\n\nexport type MessageBase<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['messageType'] & {\n id: string;\n attachments?: Attachment<StreamChatGenerics>[];\n html?: string;\n mml?: string;\n parent_id?: string;\n pin_expires?: string | null;\n pinned?: boolean;\n pinned_at?: string | null;\n poll_id?: string;\n quoted_message_id?: string;\n show_in_channel?: boolean;\n silent?: boolean;\n text?: string;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type MessageLabel = 'deleted' | 'ephemeral' | 'error' | 'regular' | 'reply' | 'system';\n\nexport type SendMessageOptions = {\n force_moderation?: boolean;\n is_pending_message?: boolean;\n keep_channel_hidden?: boolean;\n pending?: boolean;\n pending_message_metadata?: Record<string, string>;\n skip_enrich_url?: boolean;\n skip_push?: boolean;\n};\n\nexport type UpdateMessageOptions = {\n skip_enrich_url?: boolean;\n};\n\nexport type GetMessageOptions = {\n show_deleted_message?: boolean;\n};\n\nexport type Mute<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n target: UserResponse<StreamChatGenerics>;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n};\n\nexport type PartialUpdateChannel<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<ChannelResponse<StreamChatGenerics>>;\n unset?: Array<keyof ChannelResponse<StreamChatGenerics>>;\n};\n\nexport type PartialUpdateMember<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: ChannelMemberUpdates<StreamChatGenerics>;\n unset?: Array<keyof ChannelMemberUpdates<StreamChatGenerics>>;\n};\n\nexport type PartialUserUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n id: string;\n set?: Partial<UserResponse<StreamChatGenerics>>;\n unset?: Array<keyof UserResponse<StreamChatGenerics>>;\n};\n\nexport type MessageUpdatableFields<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<StreamChatGenerics>,\n 'cid' | 'created_at' | 'updated_at' | 'deleted_at' | 'user' | 'user_id'\n>;\n\nexport type PartialMessageUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<MessageUpdatableFields<StreamChatGenerics>>;\n unset?: Array<keyof MessageUpdatableFields<StreamChatGenerics>>;\n};\n\nexport type PendingMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message: MessageResponse<StreamChatGenerics>;\n pending_message_metadata?: Record<string, string>;\n};\n\nexport type PermissionAPIObject = {\n action?: string;\n condition?: object;\n custom?: boolean;\n description?: string;\n id?: string;\n level?: string;\n name?: string;\n owner?: boolean;\n same_team?: boolean;\n tags?: string[];\n};\n\nexport type PermissionObject = {\n action?: 'Deny' | 'Allow';\n name?: string;\n owner?: boolean;\n priority?: number;\n resources?: string[];\n roles?: string[];\n};\n\nexport type Policy = {\n action?: 0 | 1;\n created_at?: string;\n name?: string;\n owner?: boolean;\n priority?: number;\n resources?: string[];\n roles?: string[] | null;\n updated_at?: string;\n};\n\nexport type RateLimitsInfo = {\n limit: number;\n remaining: number;\n reset: number;\n};\n\nexport type RateLimitsMap = Record<EndpointName, RateLimitsInfo>;\n\nexport type Reaction<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['reactionType'] & {\n type: string;\n message_id?: string;\n score?: number;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type Resource =\n | 'AddLinks'\n | 'BanUser'\n | 'CreateChannel'\n | 'CreateMessage'\n | 'CreateReaction'\n | 'DeleteAttachment'\n | 'DeleteChannel'\n | 'DeleteMessage'\n | 'DeleteReaction'\n | 'EditUser'\n | 'MuteUser'\n | 'ReadChannel'\n | 'RunMessageAction'\n | 'UpdateChannel'\n | 'UpdateChannelMembers'\n | 'UpdateMessage'\n | 'UpdateUser'\n | 'UploadAttachment';\n\nexport type SearchPayload<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n SearchOptions<StreamChatGenerics>,\n 'sort'\n> & {\n client_id?: string;\n connection_id?: string;\n filter_conditions?: ChannelFilters<StreamChatGenerics>;\n message_filter_conditions?: MessageFilters<StreamChatGenerics>;\n query?: string;\n sort?: Array<{\n direction: AscDesc;\n field: keyof SearchMessageSortBase<StreamChatGenerics>;\n }>;\n};\n\nexport type TestPushDataInput = {\n apnTemplate?: string;\n firebaseDataTemplate?: string;\n firebaseTemplate?: string;\n messageID?: string;\n pushProviderName?: string;\n pushProviderType?: PushProvider;\n skipDevices?: boolean;\n};\n\nexport type TestSQSDataInput = {\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n};\n\nexport type TestSNSDataInput = {\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n};\n\nexport type TokenOrProvider = null | string | TokenProvider | undefined;\n\nexport type TokenProvider = () => Promise<string>;\n\nexport type TranslationLanguages =\n | ''\n | 'af'\n | 'am'\n | 'ar'\n | 'az'\n | 'bg'\n | 'bn'\n | 'bs'\n | 'cs'\n | 'da'\n | 'de'\n | 'el'\n | 'en'\n | 'es'\n | 'es-MX'\n | 'et'\n | 'fa'\n | 'fa-AF'\n | 'fi'\n | 'fr'\n | 'fr-CA'\n | 'ha'\n | 'he'\n | 'hi'\n | 'hr'\n | 'hu'\n | 'id'\n | 'it'\n | 'ja'\n | 'ka'\n | 'ko'\n | 'lt'\n | 'lv'\n | 'ms'\n | 'nl'\n | 'no'\n | 'pl'\n | 'ps'\n | 'pt'\n | 'ro'\n | 'ru'\n | 'sk'\n | 'sl'\n | 'so'\n | 'sq'\n | 'sr'\n | 'sv'\n | 'sw'\n | 'ta'\n | 'th'\n | 'tl'\n | 'tr'\n | 'uk'\n | 'ur'\n | 'vi'\n | 'zh'\n | 'zh-TW';\n\nexport type TypingStartEvent = Event;\n\nexport type ReservedMessageFields =\n | 'command'\n | 'created_at'\n | 'html'\n | 'latest_reactions'\n | 'own_reactions'\n | 'quoted_message'\n | 'reaction_counts'\n | 'reply_count'\n | 'type'\n | 'updated_at'\n | 'user'\n | '__html';\n\nexport type UpdatedMessage<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<StreamChatGenerics>,\n 'mentioned_users'\n> & { mentioned_users?: string[] };\n\nexport type User<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = StreamChatGenerics['userType'] & {\n id: string;\n anon?: boolean;\n name?: string;\n role?: string;\n teams?: string[];\n username?: string;\n};\n\nexport type TaskResponse = {\n task_id: string;\n};\n\nexport type DeleteChannelsResponse = {\n result: Record<string, string>;\n} & Partial<TaskResponse>;\n\nexport type DeleteType = 'soft' | 'hard' | 'pruning';\n\n/*\n DeleteUserOptions specifies a collection of one or more `user_ids` to be deleted.\n\n `user`:\n - soft: marks user as deleted and retains all user data\n - pruning: marks user as deleted and nullifies user information\n - hard: deletes user completely - this requires hard option for messages and conversation as well\n `conversations`:\n - soft: marks all conversation channels as deleted (same effect as Delete Channels with 'hard' option disabled)\n - hard: deletes channel and all its data completely including messages (same effect as Delete Channels with 'hard' option enabled)\n `messages`:\n - soft: marks all user messages as deleted without removing any related message data\n - pruning: marks all user messages as deleted, nullifies message information and removes some message data such as reactions and flags\n - hard: deletes messages completely with all related information\n `new_channel_owner_id`: any channels owned by the hard-deleted user will be transferred to this user ID\n */\nexport type DeleteUserOptions = {\n conversations?: Exclude<DeleteType, 'pruning'>;\n messages?: DeleteType;\n new_channel_owner_id?: string;\n user?: DeleteType;\n};\n\nexport type SegmentType = 'channel' | 'user';\n\nexport type SegmentData = {\n all_sender_channels?: boolean;\n all_users?: boolean;\n description?: string;\n filter?: {};\n name?: string;\n};\n\nexport type SegmentResponse = {\n created_at: string;\n deleted_at: string;\n id: string;\n locked: boolean;\n size: number;\n task_id: string;\n type: SegmentType;\n updated_at: string;\n} & SegmentData;\n\nexport type UpdateSegmentData = {\n name: string;\n} & SegmentData;\n\nexport type SegmentTargetsResponse = {\n created_at: string;\n segment_id: string;\n target_id: string;\n};\n\nexport type SortParam = {\n field: string;\n direction?: AscDesc;\n};\n\nexport type Pager = {\n limit?: number;\n next?: string;\n prev?: string;\n};\n\nexport type QuerySegmentsOptions = Pager;\n\nexport type QuerySegmentTargetsFilter = {\n target_id?: {\n $eq?: string;\n $gte?: string;\n $in?: string[];\n $lte?: string;\n };\n};\nexport type QuerySegmentTargetsOptions = Pick<Pager, 'next' | 'limit'>;\n\nexport type CampaignSort = {\n field: string;\n direction?: number;\n}[];\n\nexport type CampaignQueryOptions = {\n limit?: number;\n next?: string;\n prev?: string;\n sort?: CampaignSort;\n};\n\nexport type SegmentQueryOptions = CampaignQueryOptions;\n\n// TODO: add better typing\nexport type CampaignFilters = {};\n\nexport type CampaignData = {\n channel_template?: {\n type: string;\n custom?: {};\n id?: string;\n members?: string[];\n };\n create_channels?: boolean;\n deleted_at?: string;\n description?: string;\n id?: string | null;\n message_template?: {\n text: string;\n attachments?: Attachment[];\n custom?: {};\n poll_id?: string;\n };\n name?: string;\n segment_ids?: string[];\n sender_id?: string;\n skip_push?: boolean;\n skip_webhook?: boolean;\n user_ids?: string[];\n};\n\nexport type CampaignStats = {\n progress?: number;\n stats_channels_created?: number;\n stats_completed_at?: string;\n stats_messages_sent?: number;\n stats_started_at?: string;\n};\nexport type CampaignResponse = {\n created_at: string;\n id: string;\n segments: SegmentResponse[];\n sender: UserResponse;\n stats: CampaignStats;\n status: 'draft' | 'scheduled' | 'in_progress' | 'completed' | 'stopped';\n updated_at: string;\n users: UserResponse[];\n scheduled_for?: string;\n} & CampaignData;\n\nexport type DeleteCampaignOptions = {};\n\nexport type TaskStatus = {\n created_at: string;\n status: string;\n task_id: string;\n updated_at: string;\n error?: {\n description: string;\n type: string;\n };\n result?: UR;\n};\n\nexport type TruncateOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n hard_delete?: boolean;\n message?: Message<StreamChatGenerics>;\n skip_push?: boolean;\n truncated_at?: Date;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type CreateImportURLResponse = {\n path: string;\n upload_url: string;\n};\n\nexport type CreateImportResponse = {\n import_task: ImportTask;\n};\n\nexport type GetImportResponse = {\n import_task: ImportTask;\n};\n\nexport type CreateImportOptions = {\n mode: 'insert' | 'upsert';\n};\n\nexport type ListImportsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type ListImportsResponse = {\n import_tasks: ImportTask[];\n};\n\nexport type ImportTaskHistory = {\n created_at: string;\n next_state: string;\n prev_state: string;\n};\n\nexport type ImportTask = {\n created_at: string;\n history: ImportTaskHistory[];\n id: string;\n path: string;\n state: string;\n updated_at: string;\n result?: UR;\n size?: number;\n};\n\nexport type MessageSetType = 'latest' | 'current' | 'new';\nexport type MessageSet<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n isCurrent: boolean;\n isLatest: boolean;\n messages: FormatMessageResponse<StreamChatGenerics>[];\n pagination: { hasNext: boolean; hasPrev: boolean };\n};\n\nexport type PushProviderUpsertResponse = {\n push_provider: PushProvider;\n};\n\nexport type PushProviderListResponse = {\n push_providers: PushProvider[];\n};\n\nexport type CreateCallOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n id: string;\n type: string;\n options?: UR;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type HMSCall = {\n room: string;\n};\n\nexport type AgoraCall = {\n channel: string;\n};\n\nexport type Call = {\n id: string;\n provider: string;\n agora?: AgoraCall;\n hms?: HMSCall;\n};\n\nexport type CreateCallResponse = APIResponse & {\n call: Call;\n token: string;\n agora_app_id?: string;\n agora_uid?: number;\n};\n\nexport type GetCallTokenResponse = APIResponse & {\n token: string;\n agora_app_id?: string;\n agora_uid?: number;\n};\n\ntype ErrorResponseDetails = {\n code: number;\n messages: string[];\n};\n\nexport type APIErrorResponse = {\n code: number;\n duration: string;\n message: string;\n more_info: string;\n StatusCode: number;\n details?: ErrorResponseDetails;\n};\n\nexport class ErrorFromResponse<T> extends Error {\n code?: number;\n response?: AxiosResponse<T>;\n status?: number;\n}\n\nexport type QueryPollsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n polls: PollResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type CreatePollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type GetPollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type UpdatePollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type PollResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] &\n PollEnrichData<StreamChatGenerics> & {\n created_at: string;\n created_by: UserResponse<StreamChatGenerics> | null;\n created_by_id: string;\n enforce_unique_vote: boolean;\n id: string;\n max_votes_allowed: number;\n name: string;\n options: PollOption<StreamChatGenerics>[];\n updated_at: string;\n allow_answers?: boolean;\n allow_user_suggested_options?: boolean;\n description?: string;\n is_closed?: boolean;\n voting_visibility?: VotingVisibility;\n };\n\nexport type PollOption<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n id: string;\n poll_id: string;\n text: string;\n updated_at: string;\n vote_count: number;\n votes?: PollVote<StreamChatGenerics>[];\n};\n\nexport enum VotingVisibility {\n anonymous = 'anonymous',\n public = 'public',\n}\n\nexport type PollEnrichData<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n answers_count: number;\n latest_answers: PollAnswer<StreamChatGenerics>[]; // not updated with WS events, ordered DESC by created_at, seems like updated_at cannot be different from created_at\n latest_votes_by_option: Record<string, PollVote<StreamChatGenerics>[]>; // not updated with WS events; always null in anonymous polls\n vote_count: number;\n vote_counts_by_option: Record<string, number>;\n own_votes?: (PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>)[]; // not updated with WS events\n};\n\nexport type PollData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] & {\n id: string;\n name: string;\n allow_answers?: boolean;\n allow_user_suggested_options?: boolean;\n description?: string;\n enforce_unique_vote?: boolean;\n is_closed?: boolean;\n max_votes_allowed?: number;\n options?: PollOptionData<StreamChatGenerics>[];\n user_id?: string;\n voting_visibility?: VotingVisibility;\n};\n\nexport type CreatePollData<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n PollData<StreamChatGenerics>\n> &\n Pick<PollData<StreamChatGenerics>, 'name'>;\n\nexport type PartialPollUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<PollData<StreamChatGenerics>>;\n unset?: Array<keyof PollData<StreamChatGenerics>>;\n};\n\nexport type PollOptionData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollOptionType'] & {\n text: string;\n id?: string;\n position?: number;\n};\n\nexport type PartialPollOptionUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<PollOptionResponse<StreamChatGenerics>>;\n unset?: Array<keyof PollOptionResponse<StreamChatGenerics>>;\n};\n\nexport type PollVoteData = {\n answer_text?: string;\n is_answer?: boolean;\n option_id?: string;\n};\n\nexport type PollPaginationOptions = {\n limit?: number;\n next?: string;\n};\n\nexport type CreatePollOptionAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll_option: PollOptionResponse<StreamChatGenerics>;\n};\n\nexport type GetPollOptionAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = CreatePollOptionAPIResponse<StreamChatGenerics>;\nexport type UpdatePollOptionAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = CreatePollOptionAPIResponse<StreamChatGenerics>;\n\nexport type PollOptionResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] & {\n created_at: string;\n id: string;\n poll_id: string;\n position: number;\n text: string;\n updated_at: string;\n vote_count: number;\n votes?: PollVote<StreamChatGenerics>[];\n};\n\nexport type PollVote<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n id: string;\n poll_id: string;\n updated_at: string;\n option_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PollAnswer<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Exclude<\n PollVote<StreamChatGenerics>,\n 'option_id'\n> & {\n answer_text: string;\n is_answer: boolean; // this is absolutely redundant prop as answer_text indicates that a vote is an answer\n};\n\nexport type PollVotesAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n votes: (PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>)[];\n next?: string;\n};\n\nexport type PollAnswersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n votes: PollAnswer<StreamChatGenerics>[]; // todo: should be changes to answers?\n next?: string;\n};\n\nexport type CastVoteAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n vote: PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>;\n};\n\nexport type QueryMessageHistoryFilters = QueryFilters<\n {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageHistoryEntry['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageHistoryEntry['message_id']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageHistoryEntry['message_updated_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageHistoryEntry['message_updated_by_id']>;\n } & {\n created_at?:\n | RequireOnlyOne<\n Pick<QueryFilter<MessageHistoryEntry['message_updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>\n >\n | PrimitiveFilter<MessageHistoryEntry['message_updated_at']>;\n }\n>;\n\nexport type QueryMessageHistorySort = QueryMessageHistorySortBase | Array<QueryMessageHistorySortBase>;\n\nexport type QueryMessageHistorySortBase = {\n message_updated_at?: AscDesc;\n message_updated_by_id?: AscDesc;\n};\n\nexport type QueryMessageHistoryOptions = Pager;\n\nexport type MessageHistoryEntry<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message_id: string;\n message_updated_at: string;\n attachments?: Attachment<StreamChatGenerics>[];\n message_updated_by_id?: string;\n text?: string;\n};\n\nexport type QueryMessageHistoryResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message_history: MessageHistoryEntry<StreamChatGenerics>[];\n next?: string;\n prev?: string;\n};\n\n// Moderation v2\nexport type ModerationPayload = {\n created_at: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom?: Record<string, any>;\n images?: string[];\n texts?: string[];\n videos?: string[];\n};\n\nexport type ModV2ReviewStatus = 'complete' | 'flagged' | 'partial';\n\nexport type ModerationFlag = {\n created_at: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom: Record<string, any>;\n entity_creator_id: string;\n entity_id: string;\n entity_type: string;\n id: string;\n reason: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result: Record<string, any>[];\n review_queue_item_id: string;\n updated_at: string;\n user: UserResponse;\n moderation_payload?: ModerationPayload;\n moderation_payload_hash?: string;\n};\n\nexport type ReviewQueueItem = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n actions_taken: any[];\n appealed_by: string;\n assigned_to: string;\n completed_at: string;\n config_key: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n context: any[];\n created_at: string;\n created_by: string;\n entity_id: string;\n entity_type: string;\n flags: ModerationFlag[];\n has_image: boolean;\n has_text: boolean;\n has_video: boolean;\n id: string;\n moderation_payload: ModerationPayload;\n moderation_payload_hash: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: any;\n recommended_action: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n results: any;\n reviewed_at: string;\n status: string;\n updated_at: string;\n};\n\nexport type SubmitActionOptions = {\n ban?: {\n channel_ban_only?: boolean;\n reason?: string;\n timeout?: number;\n };\n delete_message?: {\n hard_delete?: boolean;\n };\n delete_user?: {\n delete_conversation_channels?: boolean;\n hard_delete?: boolean;\n mark_messages_deleted?: boolean;\n };\n restore?: {};\n unban?: {\n channel_cid?: string;\n };\n user_id?: string;\n};\n\nexport type GetUserModerationReportResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n user_blocks?: Array<{\n blocked_at: string;\n blocked_by_user_id: string;\n blocked_user_id: string;\n }>;\n user_mutes?: Mute<StreamChatGenerics>[];\n};\n\nexport type QueryModerationConfigsFilters = QueryFilters<\n {\n key?: string;\n } & {\n created_at?: PrimitiveFilter<string>;\n } & {\n updated_at?: PrimitiveFilter<string>;\n }\n>;\n\nexport type ReviewQueueFilters = QueryFilters<\n {\n assigned_to?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['assigned_to']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['assigned_to']>;\n } & {\n completed_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['completed_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['completed_at']>;\n } & {\n config_key?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['config_key']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['config_key']>;\n } & {\n entity_type?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['entity_type']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['entity_type']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['created_at']>;\n } & {\n id?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['id']>;\n } & {\n entity_id?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['entity_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['entity_id']>;\n } & {\n reviewed?: boolean;\n } & {\n reviewed_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['reviewed_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['reviewed_at']>;\n } & {\n status?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['status']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['status']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['updated_at']>;\n } & {\n has_image?: boolean;\n } & {\n has_text?: boolean;\n } & {\n has_video?: boolean;\n }\n>;\n\nexport type ReviewQueueSort =\n | Sort<Pick<ReviewQueueItem, 'id' | 'created_at' | 'updated_at'>>\n | Array<Sort<Pick<ReviewQueueItem, 'id' | 'created_at' | 'updated_at'>>>;\n\nexport type QueryModerationConfigsSort = Array<Sort<'key' | 'created_at' | 'updated_at'>>;\n\nexport type ReviewQueuePaginationOptions = Pager;\n\nexport type ReviewQueueResponse = {\n items: ReviewQueueItem[];\n next?: string;\n prev?: string;\n};\n\nexport type ModerationConfig = {};\n\nexport type GetConfigResponse = {\n config: ModerationConfig;\n};\n\nexport type UpsertConfigResponse = {\n config: ModerationConfig;\n};\n\nexport type ModerationFlagOptions = {\n custom?: Record<string, unknown>;\n moderation_payload?: ModerationPayload;\n user_id?: string;\n};\n\nexport type ModerationMuteOptions = {\n timeout?: number;\n user_id?: string;\n};\nexport type GetUserModerationReportOptions = {\n create_user_if_not_exists?: boolean;\n include_user_blocks?: boolean;\n include_user_mutes?: boolean;\n};\n","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}","export type Patch<T> = (value: T) => T;\nexport type Handler<T> = (nextValue: T, previousValue: T | undefined) => void;\nexport type Unsubscribe = () => void;\n\nfunction isPatch<T>(value: T | Patch<T>): value is Patch<T> {\n return typeof value === 'function';\n}\n\nexport class StateStore<T extends Record<string, unknown>> {\n private handlerSet = new Set<Handler<T>>();\n\n private static logCount = 5;\n\n constructor(private value: T) {}\n\n public next = (newValueOrPatch: T | Patch<T>): void => {\n // newValue (or patch output) should never be mutated previous value\n const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;\n\n // do not notify subscribers if the value hasn't changed\n if (newValue === this.value) return;\n\n const oldValue = this.value;\n this.value = newValue;\n\n this.handlerSet.forEach((handler) => handler(this.value, oldValue));\n };\n\n public partialNext = (partial: Partial<T>): void => this.next((current) => ({ ...current, ...partial }));\n\n public getLatestValue = (): T => this.value;\n\n public subscribe = (handler: Handler<T>): Unsubscribe => {\n handler(this.value, undefined);\n this.handlerSet.add(handler);\n return () => {\n this.handlerSet.delete(handler);\n };\n };\n\n public subscribeWithSelector = <O extends Readonly<Record<string, unknown>> | Readonly<unknown[]>>(\n selector: (nextValue: T) => O,\n handler: Handler<O>,\n ) => {\n // begin with undefined to reduce amount of selector calls\n let selectedValues: O | undefined;\n\n const wrappedHandler: Handler<T> = (nextValue) => {\n const newlySelectedValues = selector(nextValue);\n\n let hasUpdatedValues = !selectedValues;\n\n if (Array.isArray(newlySelectedValues) && StateStore.logCount > 0) {\n console.warn(\n '[StreamChat]: The API of our StateStore has changed. Instead of returning an array in the selector, please return a named object of properties.',\n );\n StateStore.logCount--;\n }\n\n for (const key in selectedValues) {\n // @ts-ignore TODO: remove array support (Readonly<unknown[]>)\n if (selectedValues[key] === newlySelectedValues[key]) continue;\n hasUpdatedValues = true;\n break;\n }\n\n if (!hasUpdatedValues) return;\n\n const oldSelectedValues = selectedValues;\n selectedValues = newlySelectedValues;\n\n handler(newlySelectedValues, oldSelectedValues);\n };\n\n return this.subscribe(wrappedHandler);\n };\n}\n","import type { Channel } from './channel';\nimport type { StreamChat } from './client';\nimport { StateStore } from './store';\nimport type {\n AscDesc,\n DefaultGenerics,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n MessagePaginationOptions,\n MessageResponse,\n ReadResponse,\n ThreadResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList, findIndexInSortedArray, formatMessage, throttle } from './utils';\n\ntype QueryRepliesOptions<SCG extends ExtendableGenerics> = {\n sort?: { created_at: AscDesc }[];\n} & MessagePaginationOptions & { user?: UserResponse<SCG>; user_id?: string };\n\nexport type ThreadState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n /**\n * Determines if the thread is currently opened and on-screen. When the thread is active,\n * all new messages are immediately marked as read.\n */\n active: boolean;\n channel: Channel<SCG>;\n createdAt: Date;\n deletedAt: Date | null;\n isLoading: boolean;\n isStateStale: boolean;\n pagination: ThreadRepliesPagination;\n /**\n * Thread is identified by and has a one-to-one relation with its parent message.\n * We use parent message id as a thread id.\n */\n parentMessage: FormatMessageResponse<SCG>;\n participants: ThreadResponse<SCG>['thread_participants'];\n read: ThreadReadState;\n replies: Array<FormatMessageResponse<SCG>>;\n replyCount: number;\n updatedAt: Date | null;\n};\n\nexport type ThreadRepliesPagination = {\n isLoadingNext: boolean;\n isLoadingPrev: boolean;\n nextCursor: string | null;\n prevCursor: string | null;\n};\n\nexport type ThreadUserReadState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n lastReadAt: Date;\n unreadMessageCount: number;\n user: UserResponse<SCG>;\n lastReadMessageId?: string;\n};\n\nexport type ThreadReadState<SCG extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n ThreadUserReadState<SCG> | undefined\n>;\n\nconst DEFAULT_PAGE_LIMIT = 50;\nconst DEFAULT_SORT: { created_at: AscDesc }[] = [{ created_at: -1 }];\nconst MARK_AS_READ_THROTTLE_TIMEOUT = 1000;\n\nexport class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<ThreadState<SCG>>;\n public readonly id: string;\n\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n private failedRepliesMap: Map<string, FormatMessageResponse<SCG>> = new Map();\n\n constructor({ client, threadData }: { client: StreamChat<SCG>; threadData: ThreadResponse<SCG> }) {\n const channel = client.channel(threadData.channel.type, threadData.channel.id, {\n name: threadData.channel.name,\n });\n channel._hydrateMembers(threadData.channel.members ?? []);\n\n // For when read object is undefined and due to that unreadMessageCount for\n // the current user isn't being incremented on message.new\n const placeholderReadResponse: ReadResponse[] = client.userID\n ? [{ user: { id: client.userID }, unread_messages: 0, last_read: new Date().toISOString() }]\n : [];\n\n this.state = new StateStore<ThreadState<SCG>>({\n active: false,\n channel,\n createdAt: new Date(threadData.created_at),\n deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,\n isLoading: false,\n isStateStale: false,\n pagination: repliesPaginationFromInitialThread(threadData),\n parentMessage: formatMessage(threadData.parent_message),\n participants: threadData.thread_participants,\n read: formatReadState(\n !threadData.read || threadData.read.length === 0 ? placeholderReadResponse : threadData.read,\n ),\n replies: threadData.latest_replies.map(formatMessage),\n replyCount: threadData.reply_count ?? 0,\n updatedAt: threadData.updated_at ? new Date(threadData.updated_at) : null,\n });\n\n this.id = threadData.parent_message_id;\n this.client = client;\n }\n\n get channel() {\n return this.state.getLatestValue().channel;\n }\n\n get hasStaleState() {\n return this.state.getLatestValue().isStateStale;\n }\n\n get ownUnreadCount() {\n return ownUnreadCountSelector(this.client.userID)(this.state.getLatestValue());\n }\n\n public activate = () => {\n this.state.partialNext({ active: true });\n };\n\n public deactivate = () => {\n this.state.partialNext({ active: false });\n };\n\n public reload = async () => {\n if (this.state.getLatestValue().isLoading) {\n return;\n }\n\n this.state.partialNext({ isLoading: true });\n\n try {\n const thread = await this.client.getThread(this.id, { watch: true });\n this.hydrateState(thread);\n } finally {\n this.state.partialNext({ isLoading: false });\n }\n };\n\n public hydrateState = (thread: Thread<SCG>) => {\n if (thread === this) {\n // skip if the instances are the same\n return;\n }\n\n if (thread.id !== this.id) {\n throw new Error(\"Cannot hydrate thread state with using thread's state\");\n }\n\n const {\n read,\n replyCount,\n replies,\n parentMessage,\n participants,\n createdAt,\n deletedAt,\n updatedAt,\n } = thread.state.getLatestValue();\n\n // Preserve pending replies and append them to the updated list of replies\n const pendingReplies = Array.from(this.failedRepliesMap.values());\n\n this.state.partialNext({\n read,\n replyCount,\n replies: pendingReplies.length ? replies.concat(pendingReplies) : replies,\n parentMessage,\n participants,\n createdAt,\n deletedAt,\n updatedAt,\n isStateStale: false,\n });\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) {\n // Thread is already listening for events and changes\n return;\n }\n\n this.unsubscribeFunctions.add(this.subscribeMarkActiveThreadRead());\n this.unsubscribeFunctions.add(this.subscribeReloadActiveStaleThread());\n this.unsubscribeFunctions.add(this.subscribeMarkThreadStale());\n this.unsubscribeFunctions.add(this.subscribeNewReplies());\n this.unsubscribeFunctions.add(this.subscribeRepliesRead());\n this.unsubscribeFunctions.add(this.subscribeMessageDeleted());\n this.unsubscribeFunctions.add(this.subscribeMessageUpdated());\n };\n\n private subscribeMarkActiveThreadRead = () => {\n return this.state.subscribeWithSelector(\n (nextValue) => ({\n active: nextValue.active,\n unreadMessageCount: ownUnreadCountSelector(this.client.userID)(nextValue),\n }),\n ({ active, unreadMessageCount }) => {\n if (!active || !unreadMessageCount) return;\n this.throttledMarkAsRead();\n },\n );\n };\n\n private subscribeReloadActiveStaleThread = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ active: nextValue.active, isStateStale: nextValue.isStateStale }),\n ({ active, isStateStale }) => {\n if (active && isStateStale) {\n this.reload();\n }\n },\n );\n\n private subscribeMarkThreadStale = () =>\n this.client.on('user.watching.stop', (event) => {\n const { channel } = this.state.getLatestValue();\n\n if (!this.client.userID || this.client.userID !== event.user?.id || event.channel?.cid !== channel.cid) {\n return;\n }\n\n this.state.partialNext({ isStateStale: true });\n }).unsubscribe;\n\n private subscribeNewReplies = () =>\n this.client.on('message.new', (event) => {\n if (!this.client.userID || event.message?.parent_id !== this.id) {\n return;\n }\n\n const isOwnMessage = event.message.user?.id === this.client.userID;\n const { active, read } = this.state.getLatestValue();\n\n this.upsertReplyLocally({\n message: event.message,\n // Message from current user could have been added optimistically,\n // so the actual timestamp might differ in the event\n timestampChanged: isOwnMessage,\n });\n\n if (active) {\n this.throttledMarkAsRead();\n }\n\n const nextRead: ThreadReadState = {};\n\n for (const userId of Object.keys(read)) {\n const userRead = read[userId];\n\n if (userRead) {\n let nextUserRead: ThreadUserReadState = userRead;\n\n if (userId === event.user?.id) {\n // The user who just sent a message to the thread has no unread messages\n // in that thread\n nextUserRead = {\n ...nextUserRead,\n lastReadAt: event.created_at ? new Date(event.created_at) : new Date(),\n user: event.user,\n unreadMessageCount: 0,\n };\n } else if (active && userId === this.client.userID) {\n // Do not increment unread count for the current user in an active thread\n } else {\n // Increment unread count for all users except the author of the new message\n nextUserRead = {\n ...nextUserRead,\n unreadMessageCount: userRead.unreadMessageCount + 1,\n };\n }\n\n nextRead[userId] = nextUserRead;\n }\n }\n\n this.state.partialNext({ read: nextRead });\n }).unsubscribe;\n\n private subscribeRepliesRead = () =>\n this.client.on('message.read', (event) => {\n if (!event.user || !event.created_at || !event.thread) return;\n if (event.thread.parent_message_id !== this.id) return;\n\n const userId = event.user.id;\n const createdAt = event.created_at;\n const user = event.user;\n\n this.state.next((current) => ({\n ...current,\n read: {\n ...current.read,\n [userId]: {\n lastReadAt: new Date(createdAt),\n user,\n lastReadMessageId: event.last_read_message_id,\n unreadMessageCount: 0,\n },\n },\n }));\n }).unsubscribe;\n\n private subscribeMessageDeleted = () =>\n this.client.on('message.deleted', (event) => {\n if (!event.message) return;\n\n // Deleted message is a reply of this thread\n if (event.message.parent_id === this.id) {\n if (event.hard_delete) {\n this.deleteReplyLocally({ message: event.message });\n } else {\n // Handle soft delete (updates deleted_at timestamp)\n this.upsertReplyLocally({ message: event.message });\n }\n }\n\n // Deleted message is parent message of this thread\n if (event.message.id === this.id) {\n this.updateParentMessageLocally({ message: event.message });\n }\n }).unsubscribe;\n\n private subscribeMessageUpdated = () => {\n const eventTypes: EventTypes[] = ['message.updated', 'reaction.new', 'reaction.deleted', 'reaction.updated'];\n\n const unsubscribeFunctions = eventTypes.map(\n (eventType) =>\n this.client.on(eventType, (event) => {\n if (event.message) {\n this.updateParentMessageOrReplyLocally(event.message);\n }\n }).unsubscribe,\n );\n\n return () => unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());\n };\n\n public unregisterSubscriptions = () => {\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public deleteReplyLocally = ({ message }: { message: MessageResponse<SCG> }) => {\n const { replies } = this.state.getLatestValue();\n\n const index = findIndexInSortedArray({\n needle: formatMessage(message),\n sortedArray: replies,\n sortDirection: 'ascending',\n selectValueToCompare: (reply) => reply.created_at.getTime(),\n });\n\n const actualIndex =\n replies[index]?.id === message.id ? index : replies[index - 1]?.id === message.id ? index - 1 : null;\n\n if (actualIndex === null) {\n return;\n }\n\n const updatedReplies = [...replies];\n updatedReplies.splice(actualIndex, 1);\n\n this.state.partialNext({\n replies: updatedReplies,\n });\n };\n\n public upsertReplyLocally = ({\n message,\n timestampChanged = false,\n }: {\n message: MessageResponse<SCG>;\n timestampChanged?: boolean;\n }) => {\n if (message.parent_id !== this.id) {\n throw new Error('Reply does not belong to this thread');\n }\n\n const formattedMessage = formatMessage(message);\n\n if (message.status === 'failed') {\n // store failed reply so that it's not lost when reloading or hydrating\n this.failedRepliesMap.set(formattedMessage.id, formattedMessage);\n } else if (this.failedRepliesMap.has(message.id)) {\n this.failedRepliesMap.delete(message.id);\n }\n\n this.state.next((current) => ({\n ...current,\n replies: addToMessageList(current.replies, formattedMessage, timestampChanged),\n }));\n };\n\n public updateParentMessageLocally = ({ message }: { message: MessageResponse<SCG> }) => {\n if (message.id !== this.id) {\n throw new Error('Message does not belong to this thread');\n }\n\n this.state.next((current) => {\n const formattedMessage = formatMessage(message);\n\n return {\n ...current,\n deletedAt: formattedMessage.deleted_at,\n parentMessage: formattedMessage,\n replyCount: message.reply_count ?? current.replyCount,\n };\n });\n };\n\n public updateParentMessageOrReplyLocally = (message: MessageResponse<SCG>) => {\n if (message.parent_id === this.id) {\n this.upsertReplyLocally({ message });\n }\n\n if (!message.parent_id && message.id === this.id) {\n this.updateParentMessageLocally({ message });\n }\n };\n\n public markAsRead = async ({ force = false }: { force?: boolean } = {}) => {\n if (this.ownUnreadCount === 0 && !force) {\n return null;\n }\n\n return await this.channel.markRead({ thread_id: this.id });\n };\n\n private throttledMarkAsRead = throttle(() => this.markAsRead(), MARK_AS_READ_THROTTLE_TIMEOUT, { trailing: true });\n\n public queryReplies = ({\n limit = DEFAULT_PAGE_LIMIT,\n sort = DEFAULT_SORT,\n ...otherOptions\n }: QueryRepliesOptions<SCG> = {}) => {\n return this.channel.getReplies(this.id, { limit, ...otherOptions }, sort);\n };\n\n public loadNextPage = ({ limit = DEFAULT_PAGE_LIMIT }: { limit?: number } = {}) => {\n return this.loadPage(limit);\n };\n\n public loadPrevPage = ({ limit = DEFAULT_PAGE_LIMIT }: { limit?: number } = {}) => {\n return this.loadPage(-limit);\n };\n\n private loadPage = async (count: number) => {\n const { pagination } = this.state.getLatestValue();\n const [loadingKey, cursorKey, insertionMethodKey] =\n count > 0\n ? (['isLoadingNext', 'nextCursor', 'push'] as const)\n : (['isLoadingPrev', 'prevCursor', 'unshift'] as const);\n\n if (pagination[loadingKey] || pagination[cursorKey] === null) return;\n\n const queryOptions = { [count > 0 ? 'id_gt' : 'id_lt']: pagination[cursorKey] };\n const limit = Math.abs(count);\n\n this.state.partialNext({ pagination: { ...pagination, [loadingKey]: true } });\n\n try {\n const data = await this.queryReplies({ ...queryOptions, limit });\n const replies = data.messages.map(formatMessage);\n const maybeNextCursor = replies.at(count > 0 ? -1 : 0)?.id ?? null;\n\n this.state.next((current) => {\n let nextReplies = current.replies;\n\n // prevent re-creating array if there's nothing to add to the current one\n if (replies.length > 0) {\n nextReplies = [...current.replies];\n nextReplies[insertionMethodKey](...replies);\n }\n\n return {\n ...current,\n replies: nextReplies,\n pagination: {\n ...current.pagination,\n [cursorKey]: data.messages.length < limit ? null : maybeNextCursor,\n [loadingKey]: false,\n },\n };\n });\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n [loadingKey]: false,\n },\n }));\n }\n };\n}\n\nconst formatReadState = (read: ReadResponse[]): ThreadReadState =>\n read.reduce<ThreadReadState>((state, userRead) => {\n state[userRead.user.id] = {\n user: userRead.user,\n lastReadMessageId: userRead.last_read_message_id,\n unreadMessageCount: userRead.unread_messages ?? 0,\n lastReadAt: new Date(userRead.last_read),\n };\n return state;\n }, {});\n\nconst repliesPaginationFromInitialThread = (thread: ThreadResponse): ThreadRepliesPagination => {\n const latestRepliesContainsAllReplies = thread.latest_replies.length === thread.reply_count;\n\n return {\n nextCursor: null,\n prevCursor: latestRepliesContainsAllReplies ? null : thread.latest_replies.at(0)?.id ?? null,\n isLoadingNext: false,\n isLoadingPrev: false,\n };\n};\n\nconst ownUnreadCountSelector = (currentUserId: string | undefined) => <\n SCG extends ExtendableGenerics = DefaultGenerics\n>(\n state: ThreadState<SCG>,\n) => (currentUserId && state.read[currentUserId]?.unreadMessageCount) || 0;\n","import {\n APIResponse,\n ModerationConfig,\n DefaultGenerics,\n ExtendableGenerics,\n GetConfigResponse,\n GetUserModerationReportResponse,\n MuteUserResponse,\n ReviewQueueFilters,\n ReviewQueuePaginationOptions,\n ReviewQueueResponse,\n ReviewQueueSort,\n UpsertConfigResponse,\n ModerationFlagOptions,\n ModerationMuteOptions,\n GetUserModerationReportOptions,\n SubmitActionOptions,\n QueryModerationConfigsFilters,\n QueryModerationConfigsSort,\n Pager,\n} from './types';\nimport { StreamChat } from './client';\nimport { normalizeQuerySort } from './utils';\n\nexport const MODERATION_ENTITY_TYPES = {\n user: 'stream:user',\n message: 'stream:chat:v1:message',\n};\n\n// Moderation class provides all the endpoints related to moderation v2.\nexport class Moderation<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n client: StreamChat<StreamChatGenerics>;\n\n constructor(client: StreamChat<StreamChatGenerics>) {\n this.client = client;\n }\n\n /**\n * Flag a user\n *\n * @param {string} flaggedUserID User ID to be flagged\n * @param {string} reason Reason for flagging the user\n * @param {Object} options Additional options for flagging the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target user\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flagUser(flaggedUserID: string, reason: string, options: ModerationFlagOptions = {}) {\n return this.flag(MODERATION_ENTITY_TYPES.user, flaggedUserID, '', reason, options);\n }\n\n /**\n * Flag a message\n *\n * @param {string} messageID Message ID to be flagged\n * @param {string} reason Reason for flagging the message\n * @param {Object} options Additional options for flagging the message\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target message\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flagMessage(messageID: string, reason: string, options: ModerationFlagOptions = {}) {\n return this.flag(MODERATION_ENTITY_TYPES.message, messageID, '', reason, options);\n }\n\n /**\n * Flag a user\n *\n * @param {string} entityType Entity type to be flagged\n * @param {string} entityId Entity ID to be flagged\n * @param {string} entityCreatorID User ID of the entity creator\n * @param {string} reason Reason for flagging the entity\n * @param {Object} options Additional options for flagging the entity\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target entity\n * @param {Object} options.moderation_payload Content to be flagged e.g., { texts: ['text1', 'text2'], images: ['image1', 'image2']}\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flag(\n entityType: string,\n entityId: string,\n entityCreatorID: string,\n reason: string,\n options: ModerationFlagOptions = {},\n ) {\n return await this.client.post<{ item_id: string } & APIResponse>(this.client.baseURL + '/api/v2/moderation/flag', {\n entity_type: entityType,\n entity_id: entityId,\n entity_creator_id: entityCreatorID,\n reason,\n ...options,\n });\n }\n\n /**\n * Mute a user\n * @param {string} targetID User ID to be muted\n * @param {Object} options Additional options for muting the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is muting the target user\n * @param {number} options.timeout Timeout for the mute in minutes\n * @returns\n */\n async muteUser(targetID: string, options: ModerationMuteOptions = {}) {\n return await this.client.post<MuteUserResponse<StreamChatGenerics> & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/mute',\n {\n target_ids: [targetID],\n ...options,\n },\n );\n }\n\n /**\n * Unmute a user\n * @param {string} targetID User ID to be unmuted\n * @param {Object} options Additional options for unmuting the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is unmuting the target user\n * @returns\n */\n async unmuteUser(\n targetID: string,\n options: {\n user_id?: string;\n },\n ) {\n return await this.client.post<{ item_id: string } & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/unmute',\n {\n target_ids: [targetID],\n ...options,\n },\n );\n }\n\n /**\n * Get moderation report for a user\n * @param {string} userID User ID for which moderation report is to be fetched\n * @param {Object} options Additional options for fetching the moderation report\n * @param {boolean} options.create_user_if_not_exists Create user if not exists\n * @param {boolean} options.include_user_blocks Include user blocks\n * @param {boolean} options.include_user_mutes Include user mutes\n */\n async getUserModerationReport(userID: string, options: GetUserModerationReportOptions = {}) {\n return await this.client.get<GetUserModerationReportResponse<StreamChatGenerics>>(\n this.client.baseURL + `/api/v2/moderation/user_report`,\n {\n user_id: userID,\n ...options,\n },\n );\n }\n\n /**\n * Query review queue\n * @param {Object} filterConditions Filter conditions for querying review queue\n * @param {Object} sort Sort conditions for querying review queue\n * @param {Object} options Pagination options for querying review queue\n */\n async queryReviewQueue(\n filterConditions: ReviewQueueFilters = {},\n sort: ReviewQueueSort = [],\n options: ReviewQueuePaginationOptions = {},\n ) {\n return await this.client.post<ReviewQueueResponse>(this.client.baseURL + '/api/v2/moderation/review_queue', {\n filter: filterConditions,\n sort: normalizeQuerySort(sort),\n ...options,\n });\n }\n\n /**\n * Upsert moderation config\n * @param {Object} config Moderation config to be upserted\n */\n async upsertConfig(config: ModerationConfig = {}) {\n return await this.client.post<UpsertConfigResponse>(this.client.baseURL + '/api/v2/moderation/config', config);\n }\n\n /**\n * Get moderation config\n * @param {string} key Key for which moderation config is to be fetched\n */\n async getConfig(key: string) {\n return await this.client.get<GetConfigResponse>(this.client.baseURL + '/api/v2/moderation/config/' + key);\n }\n\n async deleteConfig(key: string) {\n return await this.client.delete(this.client.baseURL + '/api/v2/moderation/config/' + key);\n }\n\n /**\n * Query moderation configs\n * @param {Object} filterConditions Filter conditions for querying moderation configs\n * @param {Object} sort Sort conditions for querying moderation configs\n * @param {Object} options Additional options for querying moderation configs\n */\n async queryConfigs(\n filterConditions: QueryModerationConfigsFilters,\n sort: QueryModerationConfigsSort,\n options: Pager = {},\n ) {\n return await this.client.post(this.client.baseURL + '/api/v2/moderation/configs', {\n filter: filterConditions,\n sort,\n ...options,\n });\n }\n\n async submitAction(actionType: string, itemID: string, options: SubmitActionOptions = {}) {\n return await this.client.post<{ item_id: string } & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/submit_action',\n {\n action_type: actionType,\n item_id: itemID,\n ...options,\n },\n );\n }\n\n /**\n *\n * @param {string} entityType string Type of entity to be checked E.g., stream:user, stream:chat:v1:message, or any custom string\n * @param {string} entityID string ID of the entity to be checked. This is mainly for tracking purposes\n * @param {string} entityCreatorID string ID of the entity creator\n * @param {object} moderationPayload object Content to be checked for moderation. E.g., { texts: ['text1', 'text2'], images: ['image1', 'image2']}\n * @param {Array} moderationPayload.texts array Array of texts to be checked for moderation\n * @param {Array} moderationPayload.images array Array of images to be checked for moderation\n * @param {Array} moderationPayload.videos array Array of videos to be checked for moderation\n * @param configKey\n * @param options\n * @returns\n */\n async check(\n entityType: string,\n entityID: string,\n entityCreatorID: string,\n moderationPayload: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom?: Record<string, any>;\n images?: string[];\n texts?: string[];\n videos?: string[];\n },\n configKey: string,\n options?: {\n force_sync?: boolean;\n },\n ) {\n return await this.client.post(this.client.baseURL + `/api/v2/moderation/check`, {\n entity_type: entityType,\n entity_id: entityID,\n entity_creator_id: entityCreatorID,\n moderation_payload: moderationPayload,\n config_key: configKey,\n options,\n });\n }\n}\n","import { StateStore } from './store';\nimport { throttle } from './utils';\n\nimport type { StreamChat } from './client';\nimport type { Thread } from './thread';\nimport type { DefaultGenerics, Event, ExtendableGenerics, OwnUserResponse, QueryThreadsOptions } from './types';\n\nconst DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION = 1000;\nconst MAX_QUERY_THREADS_LIMIT = 25;\nexport const THREAD_MANAGER_INITIAL_STATE = {\n active: false,\n isThreadOrderStale: false,\n threads: [],\n unreadThreadCount: 0,\n unseenThreadIds: [],\n lastConnectionDropAt: null,\n pagination: {\n isLoading: false,\n isLoadingNext: false,\n nextCursor: null,\n },\n ready: false,\n};\n\nexport type ThreadManagerState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n active: boolean;\n isThreadOrderStale: boolean;\n lastConnectionDropAt: Date | null;\n pagination: ThreadManagerPagination;\n ready: boolean;\n threads: Thread<SCG>[];\n unreadThreadCount: number;\n /**\n * List of threads that haven't been loaded in the list, but have received new messages\n * since the latest reload. Useful to display a banner prompting to reload the thread list.\n */\n unseenThreadIds: string[];\n};\n\nexport type ThreadManagerPagination = {\n isLoading: boolean;\n isLoadingNext: boolean;\n nextCursor: string | null;\n};\n\nexport class ThreadManager<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<ThreadManagerState<SCG>>;\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n private threadsByIdGetterCache: {\n threads: ThreadManagerState<SCG>['threads'];\n threadsById: Record<string, Thread<SCG> | undefined>;\n };\n\n constructor({ client }: { client: StreamChat<SCG> }) {\n this.client = client;\n this.state = new StateStore<ThreadManagerState<SCG>>(THREAD_MANAGER_INITIAL_STATE);\n\n this.threadsByIdGetterCache = { threads: [], threadsById: {} };\n }\n\n public get threadsById() {\n const { threads } = this.state.getLatestValue();\n\n if (threads === this.threadsByIdGetterCache.threads) {\n return this.threadsByIdGetterCache.threadsById;\n }\n\n const threadsById = threads.reduce<Record<string, Thread<SCG>>>((newThreadsById, thread) => {\n newThreadsById[thread.id] = thread;\n return newThreadsById;\n }, {});\n\n this.threadsByIdGetterCache.threads = threads;\n this.threadsByIdGetterCache.threadsById = threadsById;\n\n return threadsById;\n }\n\n public resetState = () => {\n this.state.next(THREAD_MANAGER_INITIAL_STATE);\n };\n\n public activate = () => {\n this.state.partialNext({ active: true });\n };\n\n public deactivate = () => {\n this.state.partialNext({ active: false });\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) return;\n\n this.unsubscribeFunctions.add(this.subscribeUnreadThreadsCountChange());\n this.unsubscribeFunctions.add(this.subscribeManageThreadSubscriptions());\n this.unsubscribeFunctions.add(this.subscribeReloadOnActivation());\n this.unsubscribeFunctions.add(this.subscribeNewReplies());\n this.unsubscribeFunctions.add(this.subscribeRecoverAfterConnectionDrop());\n this.unsubscribeFunctions.add(this.subscribeChannelDeleted());\n };\n\n private subscribeUnreadThreadsCountChange = () => {\n // initiate\n const { unread_threads: unreadThreadCount = 0 } = (this.client.user as OwnUserResponse<SCG>) ?? {};\n this.state.partialNext({ unreadThreadCount });\n\n const unsubscribeFunctions = [\n 'health.check',\n 'notification.mark_read',\n 'notification.thread_message_new',\n 'notification.channel_deleted',\n ].map(\n (eventType) =>\n this.client.on(eventType, (event) => {\n const { unread_threads: unreadThreadCount } = event.me ?? event;\n if (typeof unreadThreadCount === 'number') {\n this.state.partialNext({ unreadThreadCount });\n }\n }).unsubscribe,\n );\n\n return () => unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());\n };\n\n private subscribeChannelDeleted = () =>\n this.client.on('notification.channel_deleted', (event) => {\n const { cid } = event;\n const { threads } = this.state.getLatestValue();\n\n const newThreads = threads.filter((thread) => thread.channel.cid !== cid);\n this.state.partialNext({ threads: newThreads });\n }).unsubscribe;\n\n private subscribeManageThreadSubscriptions = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ threads: nextValue.threads }),\n ({ threads: nextThreads }, prev) => {\n const { threads: prevThreads = [] } = prev ?? {};\n // Thread instance was removed if there's no thread with the given id at all,\n // or it was replaced with a new instance\n const removedThreads = prevThreads.filter((thread) => thread !== this.threadsById[thread.id]);\n\n nextThreads.forEach((thread) => thread.registerSubscriptions());\n removedThreads.forEach((thread) => thread.unregisterSubscriptions());\n },\n );\n\n private subscribeReloadOnActivation = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ active: nextValue.active }),\n ({ active }) => {\n if (active) this.reload();\n },\n );\n\n private subscribeNewReplies = () =>\n this.client.on('notification.thread_message_new', (event: Event<SCG>) => {\n const parentId = event.message?.parent_id;\n if (!parentId) return;\n\n const { unseenThreadIds, ready } = this.state.getLatestValue();\n if (!ready) return;\n\n if (this.threadsById[parentId]) {\n this.state.partialNext({ isThreadOrderStale: true });\n } else if (!unseenThreadIds.includes(parentId)) {\n this.state.partialNext({ unseenThreadIds: unseenThreadIds.concat(parentId) });\n }\n }).unsubscribe;\n\n private subscribeRecoverAfterConnectionDrop = () => {\n const unsubscribeConnectionDropped = this.client.on('connection.changed', (event) => {\n if (event.online === false) {\n this.state.next((current) =>\n current.lastConnectionDropAt\n ? current\n : {\n ...current,\n lastConnectionDropAt: new Date(),\n },\n );\n }\n }).unsubscribe;\n\n const throttledHandleConnectionRecovered = throttle(\n () => {\n const { lastConnectionDropAt } = this.state.getLatestValue();\n if (!lastConnectionDropAt) return;\n this.reload({ force: true });\n },\n DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION,\n { trailing: true },\n );\n\n const unsubscribeConnectionRecovered = this.client.on('connection.recovered', throttledHandleConnectionRecovered)\n .unsubscribe;\n\n return () => {\n unsubscribeConnectionDropped();\n unsubscribeConnectionRecovered();\n };\n };\n\n public unregisterSubscriptions = () => {\n this.state.getLatestValue().threads.forEach((thread) => thread.unregisterSubscriptions());\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public reload = async ({ force = false } = {}) => {\n const { threads, unseenThreadIds, isThreadOrderStale, pagination, ready } = this.state.getLatestValue();\n if (pagination.isLoading) return;\n if (!force && ready && !unseenThreadIds.length && !isThreadOrderStale) return;\n const limit = threads.length + unseenThreadIds.length;\n\n try {\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoading: true,\n },\n }));\n\n const response = await this.queryThreads({\n limit: Math.min(limit, MAX_QUERY_THREADS_LIMIT) || MAX_QUERY_THREADS_LIMIT,\n });\n\n const currentThreads = this.threadsById;\n const nextThreads: Thread<SCG>[] = [];\n\n for (const incomingThread of response.threads) {\n const existingThread = currentThreads[incomingThread.id];\n\n if (existingThread) {\n // Reuse thread instances if possible\n nextThreads.push(existingThread);\n if (existingThread.hasStaleState) {\n existingThread.hydrateState(incomingThread);\n }\n } else {\n nextThreads.push(incomingThread);\n }\n }\n\n this.state.next((current) => ({\n ...current,\n threads: nextThreads,\n unseenThreadIds: [],\n isThreadOrderStale: false,\n pagination: {\n ...current.pagination,\n isLoading: false,\n nextCursor: response.next ?? null,\n },\n ready: true,\n }));\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoading: false,\n },\n }));\n }\n };\n\n public queryThreads = (options: QueryThreadsOptions = {}) => {\n return this.client.queryThreads({\n limit: 25,\n participant_limit: 10,\n reply_limit: 10,\n watch: true,\n ...options,\n });\n };\n\n public loadNextPage = async (options: Omit<QueryThreadsOptions, 'next'> = {}) => {\n const { pagination } = this.state.getLatestValue();\n\n if (pagination.isLoadingNext || !pagination.nextCursor) return;\n\n try {\n this.state.partialNext({ pagination: { ...pagination, isLoadingNext: true } });\n\n const response = await this.queryThreads({\n ...options,\n next: pagination.nextCursor,\n });\n\n this.state.next((current) => ({\n ...current,\n threads: response.threads.length ? current.threads.concat(response.threads) : current.threads,\n pagination: {\n ...current.pagination,\n nextCursor: response.next ?? null,\n isLoadingNext: false,\n },\n }));\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoadingNext: false,\n },\n }));\n }\n };\n}\n","import { StateStore } from './store';\nimport type { StreamChat } from './client';\nimport type {\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n PartialPollUpdate,\n PollAnswer,\n PollData,\n PollEnrichData,\n PollOptionData,\n PollResponse,\n PollVote,\n QueryVotesFilters,\n QueryVotesOptions,\n VoteSort,\n} from './types';\n\ntype PollEvent<SCG extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n created_at: string;\n poll: PollResponse<SCG>;\n};\n\ntype PollUpdatedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollEvent<SCG> & {\n type: 'poll.updated';\n};\n\ntype PollClosedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollEvent<SCG> & {\n type: 'poll.closed';\n};\n\ntype PollVoteEvent<SCG extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n created_at: string;\n poll: PollResponse<SCG>;\n poll_vote: PollVote<SCG> | PollAnswer<SCG>;\n};\n\ntype PollVoteCastedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_casted';\n};\n\ntype PollVoteCastedChanged<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_removed';\n};\n\ntype PollVoteCastedRemoved<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_removed';\n};\n\nconst isPollUpdatedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollUpdatedEvent<SCG> => e.type === 'poll.updated';\nconst isPollClosedEventEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollClosedEvent<SCG> => e.type === 'poll.closed';\nconst isPollVoteCastedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedEvent<SCG> => e.type === 'poll.vote_casted';\nconst isPollVoteChangedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedChanged<SCG> => e.type === 'poll.vote_changed';\nconst isPollVoteRemovedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedRemoved<SCG> => e.type === 'poll.vote_removed';\n\nexport const isVoteAnswer = <SCG extends ExtendableGenerics = DefaultGenerics>(\n vote: PollVote<SCG> | PollAnswer<SCG>,\n): vote is PollAnswer<SCG> => !!(vote as PollAnswer<SCG>)?.answer_text;\n\nexport type PollAnswersQueryParams = {\n filter?: QueryVotesFilters;\n options?: QueryVotesOptions;\n sort?: VoteSort;\n};\n\nexport type PollOptionVotesQueryParams = {\n filter: { option_id: string } & QueryVotesFilters;\n options?: QueryVotesOptions;\n sort?: VoteSort;\n};\n\ntype OptionId = string;\n\nexport type PollState<SCG extends ExtendableGenerics = DefaultGenerics> = SCG['pollType'] &\n Omit<PollResponse<SCG>, 'own_votes' | 'id'> & {\n lastActivityAt: Date; // todo: would be ideal to get this from the BE\n maxVotedOptionIds: OptionId[];\n ownVotesByOptionId: Record<OptionId, PollVote<SCG>>;\n ownAnswer?: PollAnswer; // each user can have only one answer\n };\n\ntype PollInitOptions<SCG extends ExtendableGenerics = DefaultGenerics> = {\n client: StreamChat<SCG>;\n poll: PollResponse<SCG>;\n};\n\nexport class Poll<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<PollState<SCG>>;\n public id: string;\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n\n constructor({ client, poll }: PollInitOptions<SCG>) {\n this.client = client;\n this.id = poll.id;\n\n this.state = new StateStore<PollState<SCG>>(this.getInitialStateFromPollResponse(poll));\n }\n\n private getInitialStateFromPollResponse = (poll: PollInitOptions<SCG>['poll']) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { own_votes, id, ...pollResponseForState } = poll;\n const { ownAnswer, ownVotes } = own_votes?.reduce<{ ownVotes: PollVote<SCG>[]; ownAnswer?: PollAnswer }>(\n (acc, voteOrAnswer) => {\n if (isVoteAnswer(voteOrAnswer)) {\n acc.ownAnswer = voteOrAnswer;\n } else {\n acc.ownVotes.push(voteOrAnswer);\n }\n return acc;\n },\n { ownVotes: [] },\n ) ?? { ownVotes: [] };\n\n return {\n ...pollResponseForState,\n lastActivityAt: new Date(),\n maxVotedOptionIds: getMaxVotedOptionIds(\n pollResponseForState.vote_counts_by_option as PollResponse<SCG>['vote_counts_by_option'],\n ),\n ownAnswer,\n ownVotesByOptionId: getOwnVotesByOptionId(ownVotes),\n };\n };\n\n public reinitializeState = (poll: PollInitOptions<SCG>['poll']) => {\n this.state.partialNext(this.getInitialStateFromPollResponse(poll));\n };\n\n get data(): PollState<SCG> {\n return this.state.getLatestValue();\n }\n\n public handlePollUpdated = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollUpdatedEvent(event)) return;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { id, ...pollData } = extractPollData(event.poll);\n // @ts-ignore\n this.state.partialNext({ ...pollData, lastActivityAt: new Date(event.created_at) });\n };\n\n public handlePollClosed = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollClosedEventEvent(event)) return;\n // @ts-ignore\n this.state.partialNext({ is_closed: true, lastActivityAt: new Date(event.created_at) });\n };\n\n public handleVoteCasted = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteCastedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n const ownVotesByOptionId = currentState.ownVotesByOptionId;\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isOwnVote) {\n if (isVoteAnswer(event.poll_vote)) {\n ownAnswer = event.poll_vote;\n } else if (event.poll_vote.option_id) {\n ownVotesByOptionId[event.poll_vote.option_id] = event.poll_vote;\n }\n }\n\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers];\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n public handleVoteChanged = (event: Event<SCG>) => {\n // this event is triggered only when event.poll.enforce_unique_vote === true\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteChangedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n let ownVotesByOptionId = currentState.ownVotesByOptionId;\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isOwnVote) {\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers.filter((answer) => answer.id !== event.poll_vote.id)];\n ownAnswer = event.poll_vote;\n } else if (event.poll_vote.option_id) {\n if (event.poll.enforce_unique_votes) {\n ownVotesByOptionId = { [event.poll_vote.option_id]: event.poll_vote };\n } else {\n ownVotesByOptionId = Object.entries(ownVotesByOptionId).reduce<Record<OptionId, PollVote<SCG>>>(\n (acc, [optionId, vote]) => {\n if (optionId !== event.poll_vote.option_id && vote.id === event.poll_vote.id) {\n return acc;\n }\n acc[optionId] = vote;\n return acc;\n },\n {},\n );\n ownVotesByOptionId[event.poll_vote.option_id] = event.poll_vote;\n }\n\n if (ownAnswer?.id === event.poll_vote.id) {\n ownAnswer = undefined;\n }\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n } else if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers];\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n public handleVoteRemoved = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteRemovedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n const ownVotesByOptionId = { ...currentState.ownVotesByOptionId };\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = latestAnswers.filter((answer) => answer.id !== event.poll_vote.id);\n if (isOwnVote) {\n ownAnswer = undefined;\n }\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n if (isOwnVote && event.poll_vote.option_id) {\n delete ownVotesByOptionId[event.poll_vote.option_id];\n }\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n query = async (id: string) => {\n const { poll } = await this.client.getPoll(id);\n // @ts-ignore\n this.state.partialNext({ ...poll, lastActivityAt: new Date() });\n return poll;\n };\n\n update = async (data: Exclude<PollData<SCG>, 'id'>) => {\n return await this.client.updatePoll({ ...data, id: this.id });\n };\n\n partialUpdate = async (partialPollObject: PartialPollUpdate<SCG>) => {\n return await this.client.partialUpdatePoll(this.id as string, partialPollObject);\n };\n\n close = async () => {\n return await this.client.closePoll(this.id as string);\n };\n\n delete = async () => {\n return await this.client.deletePoll(this.id as string);\n };\n\n createOption = async (option: PollOptionData) => {\n return await this.client.createPollOption(this.id as string, option);\n };\n\n updateOption = async (option: PollOptionData) => {\n return await this.client.updatePollOption(this.id as string, option);\n };\n\n deleteOption = async (optionId: string) => {\n return await this.client.deletePollOption(this.id as string, optionId);\n };\n\n castVote = async (optionId: string, messageId: string) => {\n const { max_votes_allowed, ownVotesByOptionId } = this.data;\n\n const reachedVoteLimit = max_votes_allowed && max_votes_allowed === Object.keys(ownVotesByOptionId).length;\n\n if (reachedVoteLimit) {\n let oldestVote = Object.values(ownVotesByOptionId)[0];\n Object.values(ownVotesByOptionId)\n .slice(1)\n .forEach((vote) => {\n if (!oldestVote?.created_at || new Date(vote.created_at) < new Date(oldestVote.created_at)) {\n oldestVote = vote;\n }\n });\n if (oldestVote?.id) {\n await this.removeVote(oldestVote.id, messageId);\n }\n }\n return await this.client.castPollVote(messageId, this.id as string, { option_id: optionId });\n };\n\n removeVote = async (voteId: string, messageId: string) => {\n return await this.client.removePollVote(messageId, this.id as string, voteId);\n };\n\n addAnswer = async (answerText: string, messageId: string) => {\n return await this.client.addPollAnswer(messageId, this.id as string, answerText);\n };\n\n removeAnswer = async (answerId: string, messageId: string) => {\n return await this.client.removePollVote(messageId, this.id as string, answerId);\n };\n\n queryAnswers = async (params: PollAnswersQueryParams) => {\n return await this.client.queryPollAnswers(this.id as string, params.filter, params.sort, params.options);\n };\n\n queryOptionVotes = async (params: PollOptionVotesQueryParams) => {\n return await this.client.queryPollVotes(this.id as string, params.filter, params.sort, params.options);\n };\n}\n\nfunction getMaxVotedOptionIds(voteCountsByOption: PollResponse['vote_counts_by_option']) {\n let maxVotes = 0;\n let winningOptions: string[] = [];\n for (const [id, count] of Object.entries(voteCountsByOption ?? {})) {\n if (count > maxVotes) {\n winningOptions = [id];\n maxVotes = count;\n } else if (count === maxVotes) {\n winningOptions.push(id);\n }\n }\n return winningOptions;\n}\n\nfunction getOwnVotesByOptionId<SCG extends ExtendableGenerics = DefaultGenerics>(ownVotes: PollVote<SCG>[]) {\n return !ownVotes\n ? ({} as Record<OptionId, PollVote<SCG>>)\n : ownVotes.reduce<Record<OptionId, PollVote<SCG>>>((acc, vote) => {\n if (isVoteAnswer(vote) || !vote.option_id) return acc;\n acc[vote.option_id] = vote;\n return acc;\n }, {});\n}\n\nexport function extractPollData<SCG extends ExtendableGenerics = DefaultGenerics>(\n pollResponse: PollResponse<SCG>,\n): PollData<SCG> {\n return {\n allow_answers: pollResponse.allow_answers,\n allow_user_suggested_options: pollResponse.allow_user_suggested_options,\n description: pollResponse.description,\n enforce_unique_vote: pollResponse.enforce_unique_vote,\n id: pollResponse.id,\n is_closed: pollResponse.is_closed,\n max_votes_allowed: pollResponse.max_votes_allowed,\n name: pollResponse.name,\n options: pollResponse.options,\n voting_visibility: pollResponse.voting_visibility,\n };\n}\n\nexport function extractPollEnrichedData<SCG extends ExtendableGenerics = DefaultGenerics>(\n pollResponse: PollResponse<SCG>,\n): Omit<PollEnrichData<SCG>, 'own_votes' | 'latest_answers'> {\n return {\n answers_count: pollResponse.answers_count,\n latest_votes_by_option: pollResponse.latest_votes_by_option,\n vote_count: pollResponse.vote_count,\n vote_counts_by_option: pollResponse.vote_counts_by_option,\n };\n}\n","import type { StreamChat } from './client';\nimport type {\n CreatePollData,\n DefaultGenerics,\n ExtendableGenerics,\n PollResponse,\n PollSort,\n QueryPollsFilters,\n QueryPollsOptions,\n} from './types';\nimport { Poll } from './poll';\nimport { FormatMessageResponse } from './types';\nimport { formatMessage } from './utils';\n\nexport class PollManager<SCG extends ExtendableGenerics = DefaultGenerics> {\n private client: StreamChat<SCG>;\n // The pollCache contains only polls that have been created and sent as messages\n // (i.e only polls that are coupled with a message, can be voted on and require a\n // reactive state). It shall work as a basic look-up table for our SDK to be able\n // to quickly consume poll state that will be reactive even without the polls being\n // rendered within the UI.\n private pollCache = new Map<string, Poll<SCG>>();\n private unsubscribeFunctions: Set<() => void> = new Set();\n\n constructor({ client }: { client: StreamChat<SCG> }) {\n this.client = client;\n }\n\n get data(): Map<string, Poll<SCG>> {\n return this.pollCache;\n }\n\n public fromState = (id: string) => {\n return this.pollCache.get(id);\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) {\n // Already listening for events and changes\n return;\n }\n\n this.unsubscribeFunctions.add(this.subscribeMessageNew());\n this.unsubscribeFunctions.add(this.subscribePollUpdated());\n this.unsubscribeFunctions.add(this.subscribePollClosed());\n this.unsubscribeFunctions.add(this.subscribeVoteCasted());\n this.unsubscribeFunctions.add(this.subscribeVoteChanged());\n this.unsubscribeFunctions.add(this.subscribeVoteRemoved());\n };\n\n public unregisterSubscriptions = () => {\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public createPoll = async (poll: CreatePollData<SCG>) => {\n const { poll: createdPoll } = await this.client.createPoll(poll);\n\n return new Poll({ client: this.client, poll: createdPoll });\n };\n\n public getPoll = async (id: string) => {\n const cachedPoll = this.fromState(id);\n\n // optimistically return the cached poll if it exists and update in the background\n if (cachedPoll) {\n this.client.getPoll(id).then(({ poll }) => this.setOrOverwriteInCache(poll, true));\n return cachedPoll;\n }\n // fetch it, write to the cache and return otherwise\n const { poll } = await this.client.getPoll(id);\n\n this.setOrOverwriteInCache(poll);\n\n return this.fromState(id);\n };\n\n public queryPolls = async (filter: QueryPollsFilters, sort: PollSort = [], options: QueryPollsOptions = {}) => {\n const { polls, next } = await this.client.queryPolls(filter, sort, options);\n\n const pollInstances = polls.map((poll) => {\n this.setOrOverwriteInCache(poll, true);\n\n return this.fromState(poll.id);\n });\n\n return {\n polls: pollInstances,\n next,\n };\n };\n\n public hydratePollCache = (messages: FormatMessageResponse<SCG>[], overwriteState?: boolean) => {\n for (const message of messages) {\n if (!message.poll) {\n continue;\n }\n const pollResponse = message.poll as PollResponse<SCG>;\n this.setOrOverwriteInCache(pollResponse, overwriteState);\n }\n };\n\n private setOrOverwriteInCache = (pollResponse: PollResponse<SCG>, overwriteState?: boolean) => {\n const pollFromCache = this.fromState(pollResponse.id);\n if (!pollFromCache) {\n const poll = new Poll<SCG>({ client: this.client, poll: pollResponse });\n this.pollCache.set(poll.id, poll);\n } else if (overwriteState) {\n pollFromCache.reinitializeState(pollResponse);\n }\n };\n\n private subscribePollUpdated = () => {\n return this.client.on('poll.updated', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handlePollUpdated(event);\n }\n }).unsubscribe;\n };\n\n private subscribePollClosed = () => {\n return this.client.on('poll.closed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handlePollClosed(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteCasted = () => {\n return this.client.on('poll.vote_casted', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteCasted(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteChanged = () => {\n return this.client.on('poll.vote_changed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteChanged(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteRemoved = () => {\n return this.client.on('poll.vote_removed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteRemoved(event);\n }\n }).unsubscribe;\n };\n\n private subscribeMessageNew = () => {\n return this.client.on('message.new', (event) => {\n const { message } = event;\n if (message) {\n const formattedMessage = formatMessage(message);\n this.hydratePollCache([formattedMessage]);\n }\n }).unsubscribe;\n };\n}\n","/* eslint no-unused-vars: \"off\" */\n/* global process */\n\nimport axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport https from 'https';\nimport WebSocket from 'isomorphic-ws';\n\nimport { Channel } from './channel';\nimport { ClientState } from './client_state';\nimport { StableWSConnection } from './connection';\nimport { CheckSignature, DevToken, JWTUserToken } from './signing';\nimport { TokenManager } from './token_manager';\nimport { WSConnectionFallback } from './connection_fallback';\nimport { Campaign } from './campaign';\nimport { Segment } from './segment';\nimport { isErrorResponse, isWSFailure } from './errors';\nimport {\n addFileToFormData,\n axiosParamsSerializer,\n chatCodes,\n isFunction,\n isOnline,\n isOwnUserBaseProperty,\n messageSetPagination,\n normalizeQuerySort,\n randomId,\n retryInterval,\n sleep,\n} from './utils';\n\nimport {\n APIErrorResponse,\n APIResponse,\n AppSettings,\n AppSettingsAPIResponse,\n BannedUsersFilters,\n BannedUsersPaginationOptions,\n BannedUsersResponse,\n BannedUsersSort,\n BanUserOptions,\n BaseDeviceFields,\n BlockList,\n BlockListResponse,\n BlockUserAPIResponse,\n CampaignData,\n CampaignFilters,\n CampaignQueryOptions,\n CampaignResponse,\n CampaignSort,\n CastVoteAPIResponse,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelMute,\n ChannelOptions,\n ChannelResponse,\n ChannelSort,\n ChannelStateOptions,\n CheckPushResponse,\n CheckSNSResponse,\n CheckSQSResponse,\n Configs,\n ConnectAPIResponse,\n CreateChannelOptions,\n CreateChannelResponse,\n CreateCommandOptions,\n CreateCommandResponse,\n CreateImportOptions,\n CreateImportResponse,\n CreateImportURLResponse,\n CreatePollAPIResponse,\n CreatePollData,\n CreatePollOptionAPIResponse,\n CustomPermissionOptions,\n DeactivateUsersOptions,\n DefaultGenerics,\n DeleteChannelsResponse,\n DeleteCommandResponse,\n DeleteUserOptions,\n Device,\n EndpointName,\n ErrorFromResponse,\n Event,\n EventHandler,\n ExportChannelOptions,\n ExportChannelRequest,\n ExportChannelResponse,\n ExportChannelStatusResponse,\n ExportUsersRequest,\n ExportUsersResponse,\n ExtendableGenerics,\n FlagMessageResponse,\n FlagReportsFilters,\n FlagReportsPaginationOptions,\n FlagReportsResponse,\n FlagsFilters,\n FlagsPaginationOptions,\n FlagsResponse,\n FlagUserResponse,\n GetBlockedUsersAPIResponse,\n GetCallTokenResponse,\n GetChannelTypeResponse,\n GetCommandResponse,\n GetImportResponse,\n GetMessageAPIResponse,\n GetMessageOptions,\n GetPollAPIResponse,\n GetPollOptionAPIResponse,\n GetRateLimitsResponse,\n GetThreadAPIResponse,\n GetThreadOptions,\n GetUnreadCountAPIResponse,\n GetUnreadCountBatchAPIResponse,\n ListChannelResponse,\n ListCommandsResponse,\n ListImportsPaginationOptions,\n ListImportsResponse,\n Logger,\n MarkChannelsReadOptions,\n Message,\n MessageFilters,\n MessageFlagsFilters,\n MessageFlagsPaginationOptions,\n MessageFlagsResponse,\n MessageResponse,\n Mute,\n MuteUserOptions,\n MuteUserResponse,\n OGAttachment,\n OwnUserResponse,\n PartialMessageUpdate,\n PartialPollUpdate,\n PartialThreadUpdate,\n PartialUserUpdate,\n PermissionAPIResponse,\n PermissionsAPIResponse,\n PollAnswersAPIResponse,\n PollData,\n PollOptionData,\n PollSort,\n PollVote,\n PollVoteData,\n PollVotesAPIResponse,\n PushProvider,\n PushProviderConfig,\n PushProviderID,\n PushProviderListResponse,\n PushProviderUpsertResponse,\n QueryChannelsAPIResponse,\n QueryMessageHistoryFilters,\n QueryMessageHistoryOptions,\n QueryMessageHistoryResponse,\n QueryMessageHistorySort,\n QueryPollsFilters,\n QueryPollsOptions,\n QueryPollsResponse,\n QueryReactionsAPIResponse,\n QueryReactionsOptions,\n QuerySegmentsOptions,\n QuerySegmentTargetsFilter,\n QueryThreadsAPIResponse,\n QueryThreadsOptions,\n QueryVotesFilters,\n QueryVotesOptions,\n ReactionFilters,\n ReactionResponse,\n ReactionSort,\n ReactivateUserOptions,\n ReactivateUsersOptions,\n ReservedMessageFields,\n ReviewFlagReportOptions,\n ReviewFlagReportResponse,\n SearchAPIResponse,\n SearchMessageSortBase,\n SearchOptions,\n SearchPayload,\n SegmentData,\n SegmentResponse,\n SegmentTargetsResponse,\n SegmentType,\n SendFileAPIResponse,\n SortParam,\n StreamChatOptions,\n SyncOptions,\n SyncResponse,\n TaskResponse,\n TaskStatus,\n TestPushDataInput,\n TestSNSDataInput,\n TestSQSDataInput,\n TokenOrProvider,\n UnBanUserOptions,\n UpdateChannelOptions,\n UpdateChannelResponse,\n UpdateCommandOptions,\n UpdateCommandResponse,\n UpdatedMessage,\n UpdateMessageAPIResponse,\n UpdateMessageOptions,\n UpdatePollAPIResponse,\n UpdatePollOptionAPIResponse,\n UpdateSegmentData,\n UserCustomEvent,\n UserFilters,\n UserOptions,\n UserResponse,\n UserSort,\n VoteSort,\n} from './types';\nimport { InsightMetrics, postInsights } from './insights';\nimport { Thread } from './thread';\nimport { Moderation } from './moderation';\nimport { ThreadManager } from './thread_manager';\nimport { DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE } from './constants';\nimport { PollManager } from './poll_manager';\n\nfunction isString(x: unknown): x is string {\n return typeof x === 'string' || x instanceof String;\n}\n\nexport class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n private static _instance?: unknown | StreamChat; // type is undefined|StreamChat, unknown is due to TS limitations with statics\n\n _user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>;\n activeChannels: {\n [key: string]: Channel<StreamChatGenerics>;\n };\n threads: ThreadManager<StreamChatGenerics>;\n polls: PollManager<StreamChatGenerics>;\n anonymous: boolean;\n persistUserOnConnectionFailure?: boolean;\n axiosInstance: AxiosInstance;\n baseURL?: string;\n browser: boolean;\n cleaningIntervalRef?: NodeJS.Timeout;\n clientID?: string;\n configs: Configs<StreamChatGenerics>;\n key: string;\n listeners: Record<string, Array<(event: Event<StreamChatGenerics>) => void>>;\n logger: Logger;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n moderation: Moderation<StreamChatGenerics>;\n mutedChannels: ChannelMute<StreamChatGenerics>[];\n mutedUsers: Mute<StreamChatGenerics>[];\n node: boolean;\n options: StreamChatOptions;\n secret?: string;\n setUserPromise: ConnectAPIResponse<StreamChatGenerics> | null;\n state: ClientState<StreamChatGenerics>;\n tokenManager: TokenManager<StreamChatGenerics>;\n user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>;\n userAgent?: string;\n userID?: string;\n wsBaseURL?: string;\n wsConnection: StableWSConnection<StreamChatGenerics> | null;\n wsFallback?: WSConnectionFallback<StreamChatGenerics>;\n wsPromise: ConnectAPIResponse<StreamChatGenerics> | null;\n consecutiveFailures: number;\n insightMetrics: InsightMetrics;\n defaultWSTimeoutWithFallback: number;\n defaultWSTimeout: number;\n private nextRequestAbortController: AbortController | null = null;\n\n /**\n * Initialize a client\n *\n * **Only use constructor for advanced usages. It is strongly advised to use `StreamChat.getInstance()` instead of `new StreamChat()` to reduce integration issues due to multiple WebSocket connections**\n * @param {string} key - the api key\n * @param {string} [secret] - the api secret\n * @param {StreamChatOptions} [options] - additional options, here you can pass custom options to axios instance\n * @param {boolean} [options.browser] - enforce the client to be in browser mode\n * @param {boolean} [options.warmUp] - default to false, if true, client will open a connection as soon as possible to speed up following requests\n * @param {Logger} [options.Logger] - custom logger\n * @param {number} [options.timeout] - default to 3000\n * @param {httpsAgent} [options.httpsAgent] - custom httpsAgent, in node it's default to https.agent()\n * @example <caption>initialize the client in user mode</caption>\n * new StreamChat('api_key')\n * @example <caption>initialize the client in user mode with options</caption>\n * new StreamChat('api_key', { warmUp:true, timeout:5000 })\n * @example <caption>secret is optional and only used in server side mode</caption>\n * new StreamChat('api_key', \"secret\", { httpsAgent: customAgent })\n */\n constructor(key: string, options?: StreamChatOptions);\n constructor(key: string, secret?: string, options?: StreamChatOptions);\n constructor(key: string, secretOrOptions?: StreamChatOptions | string, options?: StreamChatOptions) {\n // set the key\n this.key = key;\n this.listeners = {};\n this.state = new ClientState<StreamChatGenerics>();\n // a list of channels to hide ws events from\n this.mutedChannels = [];\n this.mutedUsers = [];\n\n this.moderation = new Moderation(this);\n\n // set the secret\n if (secretOrOptions && isString(secretOrOptions)) {\n this.secret = secretOrOptions;\n }\n\n // set the options... and figure out defaults...\n const inputOptions = options ? options : secretOrOptions && !isString(secretOrOptions) ? secretOrOptions : {};\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n\n this.options = {\n timeout: 3000,\n withCredentials: false, // making sure cookies are not sent\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n\n this.axiosInstance = axios.create(this.options);\n\n this.setBaseURL(this.options.baseURL || 'https://chat.stream-io-api.com');\n\n if (typeof process !== 'undefined' && 'env' in process && process.env.STREAM_LOCAL_TEST_RUN) {\n this.setBaseURL('http://localhost:3030');\n }\n\n if (typeof process !== 'undefined' && 'env' in process && process.env.STREAM_LOCAL_TEST_HOST) {\n this.setBaseURL('http://' + process.env.STREAM_LOCAL_TEST_HOST);\n }\n\n // WS connection is initialized when setUser is called\n this.wsConnection = null;\n this.wsPromise = null;\n this.setUserPromise = null;\n // keeps a reference to all the channels that are in use\n this.activeChannels = {};\n\n // mapping between channel groups and configs\n this.configs = {};\n this.anonymous = false;\n this.persistUserOnConnectionFailure = this.options?.persistUserOnConnectionFailure;\n\n // If its a server-side client, then lets initialize the tokenManager, since token will be\n // generated from secret.\n this.tokenManager = new TokenManager(this.secret);\n this.consecutiveFailures = 0;\n this.insightMetrics = new InsightMetrics();\n\n this.defaultWSTimeoutWithFallback = 6 * 1000;\n this.defaultWSTimeout = 15 * 1000;\n\n this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;\n\n /**\n * logger function should accept 3 parameters:\n * @param logLevel string\n * @param message string\n * @param extraData object\n *\n * e.g.,\n * const client = new StreamChat('api_key', {}, {\n * \t\tlogger = (logLevel, message, extraData) => {\n * \t\t\tconsole.log(message);\n * \t\t}\n * })\n *\n * extraData contains tags array attached to log message. Tags can have one/many of following values:\n * 1. api\n * 2. api_request\n * 3. api_response\n * 4. client\n * 5. channel\n * 6. connection\n * 7. event\n *\n * It may also contains some extra data, some examples have been mentioned below:\n * 1. {\n * \t\ttags: ['api', 'api_request', 'client'],\n * \t\turl: string,\n * \t\tpayload: object,\n * \t\tconfig: object\n * }\n * 2. {\n * \t\ttags: ['api', 'api_response', 'client'],\n * \t\turl: string,\n * \t\tresponse: object\n * }\n * 3. {\n * \t\ttags: ['api', 'api_response', 'client'],\n * \t\turl: string,\n * \t\terror: object\n * }\n * 4. {\n * \t\ttags: ['event', 'client'],\n * \t\tevent: object\n * }\n * 5. {\n * \t\ttags: ['channel'],\n * \t\tchannel: object\n * }\n */\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;\n this.threads = new ThreadManager({ client: this });\n this.polls = new PollManager({ client: this });\n }\n\n /**\n * Get a client instance\n *\n * This function always returns the same Client instance to avoid issues raised by multiple Client and WS connections\n *\n * **After the first call, the client configuration will not change if the key or options parameters change**\n *\n * @param {string} key - the api key\n * @param {string} [secret] - the api secret\n * @param {StreamChatOptions} [options] - additional options, here you can pass custom options to axios instance\n * @param {boolean} [options.browser] - enforce the client to be in browser mode\n * @param {boolean} [options.warmUp] - default to false, if true, client will open a connection as soon as possible to speed up following requests\n * @param {Logger} [options.Logger] - custom logger\n * @param {number} [options.timeout] - default to 3000\n * @param {httpsAgent} [options.httpsAgent] - custom httpsAgent, in node it's default to https.agent()\n * @example <caption>initialize the client in user mode</caption>\n * StreamChat.getInstance('api_key')\n * @example <caption>initialize the client in user mode with options</caption>\n * StreamChat.getInstance('api_key', { timeout:5000 })\n * @example <caption>secret is optional and only used in server side mode</caption>\n * StreamChat.getInstance('api_key', \"secret\", { httpsAgent: customAgent })\n */\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics>;\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n secret?: string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics>;\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n secretOrOptions?: StreamChatOptions | string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics> {\n if (!StreamChat._instance) {\n if (typeof secretOrOptions === 'string') {\n StreamChat._instance = new StreamChat<StreamChatGenerics>(key, secretOrOptions, options);\n } else {\n StreamChat._instance = new StreamChat<StreamChatGenerics>(key, secretOrOptions);\n }\n }\n\n return StreamChat._instance as StreamChat<StreamChatGenerics>;\n }\n\n devToken(userID: string) {\n return DevToken(userID);\n }\n\n getAuthType() {\n return this.anonymous ? 'anonymous' : 'jwt';\n }\n\n setBaseURL(baseURL: string) {\n this.baseURL = baseURL;\n this.wsBaseURL = this.baseURL.replace('http', 'ws').replace(':3030', ':8800');\n }\n\n _getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;\n\n _hasConnectionID = () => Boolean(this._getConnectionID());\n\n /**\n * connectUser - Set the current user and open a WebSocket connection\n *\n * @param {OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n * @param {TokenOrProvider} userTokenOrProvider Token or provider\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n connectUser = async (\n user: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>,\n userTokenOrProvider: TokenOrProvider,\n ) => {\n if (!user.id) {\n throw new Error('The \"id\" field on the user is missing');\n }\n\n /**\n * Calling connectUser multiple times is potentially the result of a bad integration, however,\n * If the user id remains the same we don't throw error\n */\n if (this.userID === user.id && this.setUserPromise) {\n console.warn(\n 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',\n );\n return this.setUserPromise;\n }\n\n if (this.userID) {\n throw new Error(\n 'Use client.disconnect() before trying to connect as a different user. connectUser was called twice.',\n );\n }\n\n if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n // we generate the client id client side\n this.userID = user.id;\n this.anonymous = false;\n\n const setTokenPromise = this._setToken(user, userTokenOrProvider);\n this._setUser(user);\n\n const wsPromise = this.openConnection();\n\n this.setUserPromise = Promise.all([setTokenPromise, wsPromise]).then(\n (result) => result[1], // We only return connection promise;\n );\n\n try {\n return await this.setUserPromise;\n } catch (err) {\n if (this.persistUserOnConnectionFailure) {\n // cleanup client to allow the user to retry connectUser again\n this.closeConnection();\n } else {\n this.disconnectUser();\n }\n throw err;\n }\n };\n\n /**\n * @deprecated Please use connectUser() function instead. Its naming is more consistent with its functionality.\n *\n * setUser - Set the current user and open a WebSocket connection\n *\n * @param {OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n * @param {TokenOrProvider} userTokenOrProvider Token or provider\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n setUser = this.connectUser;\n\n _setToken = (user: UserResponse<StreamChatGenerics>, userTokenOrProvider: TokenOrProvider) =>\n this.tokenManager.setTokenOrProvider(userTokenOrProvider, user);\n\n _setUser(user: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>) {\n /**\n * This one is used by the frontend. This is a copy of the current user object stored on backend.\n * It contains reserved properties and own user properties which are not present in `this._user`.\n */\n this.user = user;\n this.userID = user.id;\n // this one is actually used for requests. This is a copy of current user provided to `connectUser` function.\n this._user = { ...user };\n }\n\n /**\n * Disconnects the websocket connection, without removing the user set on client.\n * client.closeConnection will not trigger default auto-retry mechanism for reconnection. You need\n * to call client.openConnection to reconnect to websocket.\n *\n * This is mainly useful on mobile side. You can only receive push notifications\n * if you don't have active websocket connection.\n * So when your app goes to background, you can call `client.closeConnection`.\n * And when app comes back to foreground, call `client.openConnection`.\n *\n * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming succesful disconnection.\n * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent\n */\n closeConnection = async (timeout?: number) => {\n if (this.cleaningIntervalRef != null) {\n clearInterval(this.cleaningIntervalRef);\n this.cleaningIntervalRef = undefined;\n }\n\n await Promise.all([this.wsConnection?.disconnect(timeout), this.wsFallback?.disconnect(timeout)]);\n return Promise.resolve();\n };\n\n /**\n * Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection\n */\n openConnection = async () => {\n if (!this.userID) {\n throw Error('User is not set on client, use client.connectUser or client.connectAnonymousUser instead');\n }\n\n if (this.wsConnection?.isConnecting && this.wsPromise) {\n this.logger('info', 'client:openConnection() - connection already in progress', {\n tags: ['connection', 'client'],\n });\n return this.wsPromise;\n }\n\n if ((this.wsConnection?.isHealthy || this.wsFallback?.isHealthy()) && this._hasConnectionID()) {\n this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists', {\n tags: ['connection', 'client'],\n });\n\n return;\n }\n\n this.clientID = `${this.userID}--${randomId()}`;\n this.wsPromise = this.connect();\n this._startCleaning();\n return this.wsPromise;\n };\n\n /**\n * @deprecated Please use client.openConnction instead.\n * @private\n *\n * Creates a new websocket connection with current user.\n */\n _setupConnection = this.openConnection;\n\n /**\n * updateAppSettings - updates application settings\n *\n * @param {AppSettings} options App settings.\n * IE: {\n 'apn_config': {\n 'auth_type': 'token',\n 'auth_key\": fs.readFileSync(\n './apn-push-auth-key.p8',\n 'utf-8',\n ),\n 'key_id': 'keyid',\n 'team_id': 'teamid',\n 'notification_template\": 'notification handlebars template',\n 'bundle_id': 'com.apple.your.app',\n 'development': true\n },\n 'firebase_config': {\n 'server_key': 'server key from fcm',\n 'notification_template': 'notification handlebars template',\n 'data_template': 'data handlebars template',\n 'apn_template': 'apn notification handlebars template under v2'\n },\n 'webhook_url': 'https://acme.com/my/awesome/webhook/'\n }\n */\n async updateAppSettings(options: AppSettings) {\n const apn_config = options.apn_config;\n if (apn_config?.p12_cert) {\n options = {\n ...options,\n apn_config: {\n ...apn_config,\n p12_cert: Buffer.from(apn_config.p12_cert).toString('base64'),\n },\n };\n }\n return await this.patch<APIResponse>(this.baseURL + '/app', options);\n }\n\n _normalizeDate = (before: Date | string | null): string | null => {\n if (before instanceof Date) {\n before = before.toISOString();\n }\n\n if (before === '') {\n throw new Error(\"Don't pass blank string for since, use null instead if resetting the token revoke\");\n }\n\n return before;\n };\n\n /**\n * Revokes all tokens on application level issued before given time\n */\n async revokeTokens(before: Date | string | null) {\n return await this.updateAppSettings({\n revoke_tokens_issued_before: this._normalizeDate(before),\n });\n }\n\n /**\n * Revokes token for a user issued before given time\n */\n async revokeUserToken(userID: string, before?: Date | string | null) {\n return await this.revokeUsersToken([userID], before);\n }\n\n /**\n * Revokes tokens for a list of users issued before given time\n */\n async revokeUsersToken(userIDs: string[], before?: Date | string | null) {\n if (before === undefined) {\n before = new Date().toISOString();\n } else {\n before = this._normalizeDate(before);\n }\n\n const users: PartialUserUpdate<StreamChatGenerics>[] = [];\n for (const userID of userIDs) {\n users.push({\n id: userID,\n set: <Partial<UserResponse<StreamChatGenerics>>>{\n revoke_tokens_issued_before: before,\n },\n });\n }\n\n return await this.partialUpdateUsers(users);\n }\n\n /**\n * getAppSettings - retrieves application settings\n */\n async getAppSettings() {\n return await this.get<AppSettingsAPIResponse<StreamChatGenerics>>(this.baseURL + '/app');\n }\n\n /**\n * testPushSettings - Tests the push settings for a user with a random chat message and the configured push templates\n *\n * @param {string} userID User ID. If user has no devices, it will error\n * @param {TestPushDataInput} [data] Overrides for push templates/message used\n * IE: {\n messageID: 'id-of-message', // will error if message does not exist\n apnTemplate: '{}', // if app doesn't have apn configured it will error\n firebaseTemplate: '{}', // if app doesn't have firebase configured it will error\n firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error\n skipDevices: true, // skip config/device checks and sending to real devices\n pushProviderName: 'staging' // one of your configured push providers\n pushProviderType: 'apn' // one of supported provider types\n }\n */\n async testPushSettings(userID: string, data: TestPushDataInput = {}) {\n return await this.post<CheckPushResponse>(this.baseURL + '/check_push', {\n user_id: userID,\n ...(data.messageID ? { message_id: data.messageID } : {}),\n ...(data.apnTemplate ? { apn_template: data.apnTemplate } : {}),\n ...(data.firebaseTemplate ? { firebase_template: data.firebaseTemplate } : {}),\n ...(data.firebaseDataTemplate ? { firebase_data_template: data.firebaseDataTemplate } : {}),\n ...(data.skipDevices ? { skip_devices: true } : {}),\n ...(data.pushProviderName ? { push_provider_name: data.pushProviderName } : {}),\n ...(data.pushProviderType ? { push_provider_type: data.pushProviderType } : {}),\n });\n }\n\n /**\n * testSQSSettings - Tests that the given or configured SQS configuration is valid\n *\n * @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed\n * IE: {\n sqs_key: 'auth_key',\n sqs_secret: 'auth_secret',\n sqs_url: 'url_to_queue',\n }\n */\n async testSQSSettings(data: TestSQSDataInput = {}) {\n return await this.post<CheckSQSResponse>(this.baseURL + '/check_sqs', data);\n }\n\n /**\n * testSNSSettings - Tests that the given or configured SNS configuration is valid\n *\n * @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed\n * IE: {\n sns_key: 'auth_key',\n sns_secret: 'auth_secret',\n sns_topic_arn: 'topic_to_publish_to',\n }\n */\n async testSNSSettings(data: TestSNSDataInput = {}) {\n return await this.post<CheckSNSResponse>(this.baseURL + '/check_sns', data);\n }\n\n /**\n * Disconnects the websocket and removes the user from client.\n *\n * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming successful disconnection.\n * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent\n */\n disconnectUser = async (timeout?: number) => {\n this.logger('info', 'client:disconnect() - Disconnecting the client', {\n tags: ['connection', 'client'],\n });\n\n // remove the user specific fields\n delete this.user;\n delete this._user;\n delete this.userID;\n\n this.anonymous = false;\n\n const closePromise = this.closeConnection(timeout);\n\n for (const channel of Object.values(this.activeChannels)) {\n channel._disconnect();\n }\n // ensure we no longer return inactive channels\n this.activeChannels = {};\n // reset client state\n this.state = new ClientState();\n // reset thread manager\n this.threads.resetState();\n // reset token manager\n setTimeout(this.tokenManager.reset); // delay reseting to use token for disconnect calls\n\n // close the WS connection\n return closePromise;\n };\n\n /**\n *\n * @deprecated Please use client.disconnectUser instead.\n *\n * Disconnects the websocket and removes the user from client.\n */\n disconnect = this.disconnectUser;\n\n /**\n * connectAnonymousUser - Set an anonymous user and open a WebSocket connection\n */\n connectAnonymousUser = () => {\n if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n this.anonymous = true;\n this.userID = randomId();\n const anonymousUser = {\n id: this.userID,\n anon: true,\n } as UserResponse<StreamChatGenerics>;\n\n this._setToken(anonymousUser, '');\n this._setUser(anonymousUser);\n\n return this._setupConnection();\n };\n\n /**\n * @deprecated Please use connectAnonymousUser. Its naming is more consistent with its functionality.\n */\n setAnonymousUser = this.connectAnonymousUser;\n\n /**\n * setGuestUser - Setup a temporary guest user\n *\n * @param {UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n async setGuestUser(user: UserResponse<StreamChatGenerics>) {\n let response: { access_token: string; user: UserResponse<StreamChatGenerics> } | undefined;\n this.anonymous = true;\n try {\n response = await this.post<\n APIResponse & {\n access_token: string;\n user: UserResponse<StreamChatGenerics>;\n }\n >(this.baseURL + '/guest', { user });\n } catch (e) {\n this.anonymous = false;\n throw e;\n }\n this.anonymous = false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { created_at, updated_at, last_active, online, ...guestUser } = response.user;\n return await this.connectUser(guestUser as UserResponse<StreamChatGenerics>, response.access_token);\n }\n\n /**\n * createToken - Creates a token to authenticate this user. This function is used server side.\n * The resulting token should be passed to the client side when the users registers or logs in.\n *\n * @param {string} userID The User ID\n * @param {number} [exp] The expiration time for the token expressed in the number of seconds since the epoch\n *\n * @return {string} Returns a token\n */\n createToken(userID: string, exp?: number, iat?: number) {\n if (this.secret == null) {\n throw Error(`tokens can only be created server-side using the API Secret`);\n }\n const extra: { exp?: number; iat?: number } = {};\n\n if (exp) {\n extra.exp = exp;\n }\n\n if (iat) {\n extra.iat = iat;\n }\n\n return JWTUserToken(this.secret, userID, extra, {});\n }\n\n /**\n * on - Listen to events on all channels and users your watching\n *\n * client.on('message.new', event => {console.log(\"my new message\", event, channel.state.messages)})\n * or\n * client.on(event => {console.log(event.type)})\n *\n * @param {EventHandler<StreamChatGenerics> | string} callbackOrString The event type to listen for (optional)\n * @param {EventHandler<StreamChatGenerics>} [callbackOrNothing] The callback to call\n *\n * @return {{ unsubscribe: () => void }} Description\n */\n on(callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(eventType: string, callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<StreamChatGenerics> | string,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<StreamChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this.logger('info', `Attaching listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key].push(callback);\n return {\n unsubscribe: () => {\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n /**\n * off - Remove the event handler\n *\n */\n off(callback: EventHandler<StreamChatGenerics>): void;\n off(eventType: string, callback: EventHandler<StreamChatGenerics>): void;\n off(\n callbackOrString: EventHandler<StreamChatGenerics> | string,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ) {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<StreamChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger('info', `client: ${type} - Request - ${url}`, {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n });\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown) {\n this.logger('error', `client:${type} - Error - url: ${url}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n });\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n await this.tokenManager.tokenReady();\n const requestConfig = this._enrichAxiosOptions(options);\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e);\n this.consecutiveFailures += 1;\n if (e.response) {\n /** connection_fallback depends on this token expiration logic */\n if (e.response.data.code === chatCodes.TOKEN_EXPIRED && !this.tokenManager.isStatic()) {\n if (this.consecutiveFailures > 1) {\n await sleep(retryInterval(this.consecutiveFailures));\n }\n this.tokenManager.loadToken();\n return await this.doAxiosRequest<T>(type, url, data, options);\n }\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('post', url, data);\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n\n sendFile(\n url: string,\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n const data = addFileToFormData(uri, name, contentType || 'multipart/form-data');\n if (user != null) data.append('user', JSON.stringify(user));\n\n return this.doAxiosRequest<SendFileAPIResponse>('postForm', url, data, {\n headers: data.getHeaders ? data.getHeaders() : {}, // node vs browser\n config: {\n timeout: 0,\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n },\n });\n }\n\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`StreamChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`StreamChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n dispatchEvent = (event: Event<StreamChatGenerics>) => {\n if (!event.received_at) event.received_at = new Date();\n\n // client event handlers\n const postListenerCallbacks = this._handleClientEvent(event);\n\n // channel event handlers\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n };\n\n handleEvent = (messageEvent: WebSocket.MessageEvent) => {\n // dispatch the event to the channel listeners\n const jsonString = messageEvent.data as string;\n const event = JSON.parse(jsonString) as Event<StreamChatGenerics>;\n this.dispatchEvent(event);\n };\n\n /**\n * Updates the members, watchers and read references of the currently active channels that contain this user\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n _updateMemberWatcherReferences = (user: UserResponse<StreamChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n if (channel?.state) {\n if (channel.state.members[user.id]) {\n channel.state.members[user.id].user = user;\n }\n if (channel.state.watchers[user.id]) {\n channel.state.watchers[user.id] = user;\n }\n if (channel.state.read[user.id]) {\n channel.state.read[user.id].user = user;\n }\n }\n }\n };\n\n /**\n * @deprecated Please _updateMemberWatcherReferences instead.\n * @private\n */\n _updateUserReferences = this._updateMemberWatcherReferences;\n\n /**\n * @private\n *\n * Updates the messages from the currently active channels that contain this user,\n * with updated user object.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n _updateUserMessageReferences = (user: UserResponse<StreamChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n\n if (!channel) continue;\n\n const state = channel.state;\n\n /** update the messages from this user. */\n state?.updateUserMessages(user);\n }\n };\n\n /**\n * @private\n *\n * Deletes the messages from the currently active channels that contain this user\n *\n * If hardDelete is true, all the content of message will be stripped down.\n * Otherwise, only 'message.type' will be set as 'deleted'.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n * @param {boolean} hardDelete\n */\n _deleteUserMessageReference = (user: UserResponse<StreamChatGenerics>, hardDelete = false) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n const state = channel.state;\n\n /** deleted the messages from this user. */\n state?.deleteUserMessages(user, hardDelete);\n }\n };\n\n /**\n * @private\n *\n * Handle following user related events:\n * - user.presence.changed\n * - user.updated\n * - user.deleted\n *\n * @param {Event} event\n */\n _handleUserEvent = (event: Event<StreamChatGenerics>) => {\n if (!event.user) {\n return;\n }\n\n /** update the client.state with any changes to users */\n if (event.type === 'user.presence.changed' || event.type === 'user.updated') {\n if (event.user.id === this.userID) {\n const user = { ...(this.user || {}) };\n const _user = { ...(this._user || {}) };\n\n // Remove deleted properties from user objects.\n for (const key in this.user) {\n if (key in event.user || isOwnUserBaseProperty(key)) {\n continue;\n }\n\n delete user[key];\n delete _user[key];\n }\n\n /** Updating only available properties in _user object. */\n for (const key in event.user) {\n if (_user && key in _user) {\n _user[key] = event.user[key];\n }\n }\n\n // @ts-expect-error\n this._user = { ..._user };\n this.user = { ...user, ...event.user };\n }\n\n this.state.updateUser(event.user);\n this._updateMemberWatcherReferences(event.user);\n }\n\n if (event.type === 'user.updated') {\n this._updateUserMessageReferences(event.user);\n }\n\n if (event.type === 'user.deleted' && event.user.deleted_at && (event.mark_messages_deleted || event.hard_delete)) {\n this._deleteUserMessageReference(event.user, event.hard_delete);\n }\n };\n\n _handleClientEvent(event: Event<StreamChatGenerics>) {\n const client = this;\n const postListenerCallbacks = [];\n this.logger('info', `client:_handleClientEvent - Received event of type { ${event.type} }`, {\n tags: ['event', 'client'],\n event,\n });\n\n if (event.type === 'user.presence.changed' || event.type === 'user.updated' || event.type === 'user.deleted') {\n this._handleUserEvent(event);\n }\n\n if (event.type === 'health.check' && event.me) {\n client.user = event.me;\n client.state.updateUser(event.me);\n client.mutedChannels = event.me.channel_mutes;\n client.mutedUsers = event.me.mutes;\n }\n\n if (event.channel && event.type === 'notification.message_new') {\n this._addChannelConfig(event.channel);\n }\n\n if (event.type === 'notification.channel_mutes_updated' && event.me?.channel_mutes) {\n this.mutedChannels = event.me.channel_mutes;\n }\n\n if (event.type === 'notification.mutes_updated' && event.me?.mutes) {\n this.mutedUsers = event.me.mutes;\n }\n\n if (event.type === 'notification.mark_read' && event.unread_channels === 0) {\n const activeChannelKeys = Object.keys(this.activeChannels);\n activeChannelKeys.forEach((activeChannelKey) => (this.activeChannels[activeChannelKey].state.unreadCount = 0));\n }\n\n if ((event.type === 'channel.deleted' || event.type === 'notification.channel_deleted') && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n }\n\n return postListenerCallbacks;\n }\n\n _muteStatus(cid: string) {\n let muteStatus;\n for (let i = 0; i < this.mutedChannels.length; i++) {\n const mute = this.mutedChannels[i];\n if (mute.channel?.cid === cid) {\n muteStatus = {\n muted: mute.expires ? new Date(mute.expires).getTime() > new Date().getTime() : true,\n createdAt: mute.created_at ? new Date(mute.created_at) : new Date(),\n expiresAt: mute.expires ? new Date(mute.expires) : null,\n };\n break;\n }\n }\n\n if (muteStatus) {\n return muteStatus;\n }\n\n return {\n muted: false,\n createdAt: null,\n expiresAt: null,\n };\n }\n\n _callClientListeners = (event: Event<StreamChatGenerics>) => {\n const client = this;\n // gather and call the listeners\n const listeners: Array<(event: Event<StreamChatGenerics>) => void> = [];\n if (client.listeners.all) {\n listeners.push(...client.listeners.all);\n }\n if (client.listeners[event.type]) {\n listeners.push(...client.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n listener(event);\n }\n };\n\n recoverState = async () => {\n this.logger('info', `client:recoverState() - Start of recoverState with connectionID ${this._getConnectionID()}`, {\n tags: ['connection'],\n });\n\n const cids = Object.keys(this.activeChannels);\n if (cids.length && this.recoverStateOnReconnect) {\n this.logger('info', `client:recoverState() - Start the querying of ${cids.length} channels`, {\n tags: ['connection', 'client'],\n });\n\n await this.queryChannels(\n { cid: { $in: cids } } as ChannelFilters<StreamChatGenerics>,\n { last_message_at: -1 },\n { limit: 30 },\n );\n\n this.logger('info', 'client:recoverState() - Querying channels finished', { tags: ['connection', 'client'] });\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<StreamChatGenerics>);\n } else {\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<StreamChatGenerics>);\n }\n\n this.wsPromise = Promise.resolve();\n this.setUserPromise = Promise.resolve();\n };\n\n /**\n * @private\n */\n async connect() {\n if (!this.userID || !this._user) {\n throw Error('Call connectUser or connectAnonymousUser before starting the connection');\n }\n if (!this.wsBaseURL) {\n throw Error('Websocket base url not set');\n }\n if (!this.clientID) {\n throw Error('clientID is not set');\n }\n\n if (!this.wsConnection && (this.options.warmUp || this.options.enableInsights)) {\n this._sayHi();\n }\n // The StableWSConnection handles all the reconnection logic.\n if (this.options.wsConnection && this.node) {\n // Intentionally avoiding adding ts generics on wsConnection in options since its only useful for unit test purpose.\n ((this.options.wsConnection as unknown) as StableWSConnection<StreamChatGenerics>).setClient(this);\n this.wsConnection = (this.options.wsConnection as unknown) as StableWSConnection<StreamChatGenerics>;\n } else {\n this.wsConnection = new StableWSConnection<StreamChatGenerics>({\n client: this,\n });\n }\n\n try {\n // if fallback is used before, continue using it instead of waiting for WS to fail\n if (this.wsFallback) {\n return await this.wsFallback.connect();\n }\n\n // if WSFallback is enabled, ws connect should timeout faster so fallback can try\n return await this.wsConnection.connect(\n this.options.enableWSFallback ? this.defaultWSTimeoutWithFallback : this.defaultWSTimeout,\n );\n } catch (err) {\n // run fallback only if it's WS/Network error and not a normal API error\n // make sure browser is online before even trying the longpoll\n if (this.options.enableWSFallback && isWSFailure(err) && isOnline()) {\n this.logger('info', 'client:connect() - WS failed, fallback to longpoll', { tags: ['connection', 'client'] });\n this.dispatchEvent({ type: 'transport.changed', mode: 'longpoll' });\n\n this.wsConnection._destroyCurrentWSConnection();\n this.wsConnection.disconnect().then(); // close WS so no retry\n this.wsFallback = new WSConnectionFallback<StreamChatGenerics>({\n client: this,\n });\n return await this.wsFallback.connect();\n }\n\n throw err;\n }\n }\n\n /**\n * Check the connectivity with server for warmup purpose.\n *\n * @private\n */\n _sayHi() {\n const client_request_id = randomId();\n const opts = { headers: { 'x-client-request-id': client_request_id } };\n this.doAxiosRequest('get', this.baseURL + '/hi', null, opts).catch((e) => {\n if (this.options.enableInsights) {\n postInsights('http_hi_failed', {\n api_key: this.key,\n err: e,\n client_request_id,\n });\n }\n });\n }\n\n /**\n * queryUsers - Query users and watch user presence\n *\n * @param {UserFilters<StreamChatGenerics>} filterConditions MongoDB style filter conditions\n * @param {UserSort<StreamChatGenerics>} sort Sort options, for instance [{last_active: -1}].\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_active: -1}, {created_at: 1}]\n * @param {UserOptions} options Option object, {presence: true}\n *\n * @return {Promise<{ users: Array<UserResponse<StreamChatGenerics>> }>} User Query Response\n */\n async queryUsers(\n filterConditions: UserFilters<StreamChatGenerics>,\n sort: UserSort<StreamChatGenerics> = [],\n options: UserOptions = {},\n ) {\n const defaultOptions = {\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n if (!this._hasConnectionID()) {\n defaultOptions.presence = false;\n }\n\n // Return a list of users\n const data = await this.get<APIResponse & { users: Array<UserResponse<StreamChatGenerics>> }>(\n this.baseURL + '/users',\n {\n payload: {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...defaultOptions,\n ...options,\n },\n },\n );\n\n this.state.updateUsers(data.users);\n\n return data;\n }\n\n /**\n * queryBannedUsers - Query user bans\n *\n * @param {BannedUsersFilters} filterConditions MongoDB style filter conditions\n * @param {BannedUsersSort} sort Sort options [{created_at: 1}].\n * @param {BannedUsersPaginationOptions} options Option object, {limit: 10, offset:0, exclude_expired_bans: true}\n *\n * @return {Promise<BannedUsersResponse<StreamChatGenerics>>} Ban Query Response\n */\n async queryBannedUsers(\n filterConditions: BannedUsersFilters = {},\n sort: BannedUsersSort = [],\n options: BannedUsersPaginationOptions = {},\n ) {\n // Return a list of user bans\n return await this.get<BannedUsersResponse<StreamChatGenerics>>(this.baseURL + '/query_banned_users', {\n payload: {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n });\n }\n\n /**\n * queryMessageFlags - Query message flags\n *\n * @param {MessageFlagsFilters} filterConditions MongoDB style filter conditions\n * @param {MessageFlagsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<MessageFlagsResponse<StreamChatGenerics>>} Message Flags Response\n */\n async queryMessageFlags(filterConditions: MessageFlagsFilters = {}, options: MessageFlagsPaginationOptions = {}) {\n // Return a list of message flags\n return await this.get<MessageFlagsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flags/message', {\n payload: { filter_conditions: filterConditions, ...options },\n });\n }\n\n /**\n * queryChannels - Query channels\n *\n * @param {ChannelFilters<StreamChatGenerics>} filterConditions object MongoDB style filters\n * @param {ChannelSort<StreamChatGenerics>} [sort] Sort options, for instance {created_at: -1}.\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_updated: -1}, {created_at: 1}]\n * @param {ChannelOptions} [options] Options object\n * @param {ChannelStateOptions} [stateOptions] State options object. These options will only be used for state management and won't be sent in the request.\n * - stateOptions.skipInitialization - Skips the initialization of the state for the channels matching the ids in the list.\n *\n * @return {Promise<{ channels: Array<ChannelAPIResponse<AStreamChatGenerics>>}> } search channels response\n */\n async queryChannels(\n filterConditions: ChannelFilters<StreamChatGenerics>,\n sort: ChannelSort<StreamChatGenerics> = [],\n options: ChannelOptions = {},\n stateOptions: ChannelStateOptions = {},\n ) {\n const defaultOptions: ChannelOptions = {\n state: true,\n watch: true,\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n if (!this._hasConnectionID()) {\n defaultOptions.watch = false;\n }\n\n // Return a list of channels\n const payload = {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...defaultOptions,\n ...options,\n };\n\n const data = await this.post<QueryChannelsAPIResponse<StreamChatGenerics>>(this.baseURL + '/channels', payload);\n\n this.dispatchEvent({\n type: 'channels.queried',\n queriedChannels: {\n channels: data.channels,\n isLatestMessageSet: true,\n },\n });\n\n return this.hydrateActiveChannels(data.channels, stateOptions, options);\n }\n\n /**\n * queryReactions - Query reactions\n *\n * @param {ReactionFilters<StreamChatGenerics>} filter object MongoDB style filters\n * @param {ReactionSort<StreamChatGenerics>} [sort] Sort options, for instance {created_at: -1}.\n * @param {QueryReactionsOptions} [options] Pagination object\n *\n * @return {Promise<{ QueryReactionsAPIResponse } search channels response\n */\n async queryReactions(\n messageID: string,\n filter: ReactionFilters<StreamChatGenerics>,\n sort: ReactionSort<StreamChatGenerics> = [],\n options: QueryReactionsOptions = {},\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n // Return a list of channels\n const payload = {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n };\n\n return await this.post<QueryReactionsAPIResponse<StreamChatGenerics>>(\n this.baseURL + '/messages/' + encodeURIComponent(messageID) + '/reactions',\n payload,\n );\n }\n\n hydrateActiveChannels(\n channelsFromApi: ChannelAPIResponse<StreamChatGenerics>[] = [],\n stateOptions: ChannelStateOptions = {},\n queryChannelsOptions?: ChannelOptions,\n ) {\n const { skipInitialization, offlineMode = false } = stateOptions;\n const channels: Channel<StreamChatGenerics>[] = [];\n\n for (const channelState of channelsFromApi) {\n this._addChannelConfig(channelState.channel);\n const c = this.channel(channelState.channel.type, channelState.channel.id);\n c.data = channelState.channel;\n c.offlineMode = offlineMode;\n c.initialized = !offlineMode;\n\n let updatedMessagesSet;\n if (skipInitialization === undefined) {\n const { messageSet } = c._initializeState(channelState, 'latest');\n updatedMessagesSet = messageSet;\n } else if (!skipInitialization.includes(channelState.channel.id)) {\n c.state.clearMessages();\n const { messageSet } = c._initializeState(channelState, 'latest');\n updatedMessagesSet = messageSet;\n }\n\n if (updatedMessagesSet) {\n updatedMessagesSet.pagination = {\n ...updatedMessagesSet.pagination,\n ...messageSetPagination({\n parentSet: updatedMessagesSet,\n requestedPageSize: queryChannelsOptions?.message_limit || DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE,\n returnedPage: channelState.messages,\n logger: this.logger,\n }),\n };\n this.polls.hydratePollCache(updatedMessagesSet.messages, true);\n }\n\n channels.push(c);\n }\n\n return channels;\n }\n\n /**\n * search - Query messages\n *\n * @param {ChannelFilters<StreamChatGenerics>} filterConditions MongoDB style filter conditions\n * @param {MessageFilters<StreamChatGenerics> | string} query search query or object MongoDB style filters\n * @param {SearchOptions<StreamChatGenerics>} [options] Option object, {user_id: 'tommaso'}\n *\n * @return {Promise<SearchAPIResponse<StreamChatGenerics>>} search messages response\n */\n async search(\n filterConditions: ChannelFilters<StreamChatGenerics>,\n query: string | MessageFilters<StreamChatGenerics>,\n options: SearchOptions<StreamChatGenerics> = {},\n ) {\n if (options.offset && options.next) {\n throw Error(`Cannot specify offset with next`);\n }\n const payload: SearchPayload<StreamChatGenerics> = {\n filter_conditions: filterConditions,\n ...options,\n sort: options.sort ? normalizeQuerySort<SearchMessageSortBase<StreamChatGenerics>>(options.sort) : undefined,\n };\n if (typeof query === 'string') {\n payload.query = query;\n } else if (typeof query === 'object') {\n payload.message_filter_conditions = query;\n } else {\n throw Error(`Invalid type ${typeof query} for query parameter`);\n }\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n return await this.get<SearchAPIResponse<StreamChatGenerics>>(this.baseURL + '/search', { payload });\n }\n\n /**\n * setLocalDevice - Set the device info for the current client(device) that will be sent via WS connection automatically\n *\n * @param {BaseDeviceFields} device the device object\n * @param {string} device.id device id\n * @param {string} device.push_provider the push provider\n *\n */\n setLocalDevice(device: BaseDeviceFields) {\n if (\n (this.wsConnection?.isConnecting && this.wsPromise) ||\n ((this.wsConnection?.isHealthy || this.wsFallback?.isHealthy()) && this._hasConnectionID())\n ) {\n throw new Error('you can only set device before opening a websocket connection');\n }\n\n this.options.device = device;\n }\n\n /**\n * addDevice - Adds a push device for a user.\n *\n * @param {string} id the device id\n * @param {PushProvider} push_provider the push provider\n * @param {string} [userID] the user id (defaults to current user)\n * @param {string} [push_provider_name] user provided push provider name for multi bundle support\n *\n */\n async addDevice(id: string, push_provider: PushProvider, userID?: string, push_provider_name?: string) {\n return await this.post<APIResponse>(this.baseURL + '/devices', {\n id,\n push_provider,\n ...(userID != null ? { user_id: userID } : {}),\n ...(push_provider_name != null ? { push_provider_name } : {}),\n });\n }\n\n /**\n * getDevices - Returns the devices associated with a current user\n *\n * @param {string} [userID] User ID. Only works on serverside\n *\n * @return {Device<StreamChatGenerics>[]} Array of devices\n */\n async getDevices(userID?: string) {\n return await this.get<APIResponse & { devices?: Device<StreamChatGenerics>[] }>(\n this.baseURL + '/devices',\n userID ? { user_id: userID } : {},\n );\n }\n\n /**\n * getUnreadCount - Returns unread counts for a single user\n *\n * @param {string} [userID] User ID.\n *\n * @return {<GetUnreadCountAPIResponse>}\n */\n async getUnreadCount(userID?: string) {\n return await this.get<GetUnreadCountAPIResponse>(this.baseURL + '/unread', userID ? { user_id: userID } : {});\n }\n\n /**\n * getUnreadCountBatch - Returns unread counts for multiple users at once. Only works server side.\n *\n * @param {string[]} [userIDs] List of user IDs to fetch unread counts for.\n *\n * @return {<GetUnreadCountBatchAPIResponse>}\n */\n async getUnreadCountBatch(userIDs: string[]) {\n return await this.post<GetUnreadCountBatchAPIResponse>(this.baseURL + '/unread_batch', { user_ids: userIDs });\n }\n\n /**\n * removeDevice - Removes the device with the given id. Clientside users can only delete their own devices\n *\n * @param {string} id The device id\n * @param {string} [userID] The user id. Only specify this for serverside requests\n *\n */\n async removeDevice(id: string, userID?: string) {\n return await this.delete<APIResponse>(this.baseURL + '/devices', {\n id,\n ...(userID ? { user_id: userID } : {}),\n });\n }\n\n /**\n * getRateLimits - Returns the rate limits quota and usage for the current app, possibly filter for a specific platform and/or endpoints.\n * Only available server-side.\n *\n * @param {object} [params] The params for the call. If none of the params are set, all limits for all platforms are returned.\n * @returns {Promise<GetRateLimitsResponse>}\n */\n async getRateLimits(params?: {\n android?: boolean;\n endpoints?: EndpointName[];\n ios?: boolean;\n serverSide?: boolean;\n web?: boolean;\n }) {\n const { serverSide, web, android, ios, endpoints } = params || {};\n return this.get<GetRateLimitsResponse>(this.baseURL + '/rate_limits', {\n server_side: serverSide,\n web,\n android,\n ios,\n endpoints: endpoints ? endpoints.join(',') : undefined,\n });\n }\n\n _addChannelConfig({ cid, config }: ChannelResponse<StreamChatGenerics>) {\n this.configs[cid] = config;\n }\n\n /**\n * channel - Returns a new channel with the given type, id and custom data\n *\n * If you want to create a unique conversation between 2 or more users; you can leave out the ID parameter and provide the list of members.\n * Make sure to await channel.create() or channel.watch() before accessing channel functions:\n * ie. channel = client.channel(\"messaging\", {members: [\"tommaso\", \"thierry\"]})\n * await channel.create() to assign an ID to channel\n *\n * @param {string} channelType The channel type\n * @param {string | ChannelData<StreamChatGenerics> | null} [channelIDOrCustom] The channel ID, you can leave this out if you want to create a conversation channel\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n channel(\n channelType: string,\n channelID?: string | null,\n custom?: ChannelData<StreamChatGenerics>,\n ): Channel<StreamChatGenerics>;\n channel(channelType: string, custom?: ChannelData<StreamChatGenerics>): Channel<StreamChatGenerics>;\n channel(\n channelType: string,\n channelIDOrCustom?: string | ChannelData<StreamChatGenerics> | null,\n custom: ChannelData<StreamChatGenerics> = {} as ChannelData<StreamChatGenerics>,\n ) {\n if (!this.userID && !this._isUsingServerAuth()) {\n throw Error('Call connectUser or connectAnonymousUser before creating a channel');\n }\n\n if (~channelType.indexOf(':')) {\n throw Error(`Invalid channel group ${channelType}, can't contain the : character`);\n }\n\n // support channel(\"messaging\", {options})\n if (channelIDOrCustom && typeof channelIDOrCustom === 'object') {\n return this.getChannelByMembers(channelType, channelIDOrCustom);\n }\n\n // // support channel(\"messaging\", undefined, {options})\n if (!channelIDOrCustom && typeof custom === 'object' && custom.members?.length) {\n return this.getChannelByMembers(channelType, custom);\n }\n\n // support channel(\"messaging\", null, {options})\n // support channel(\"messaging\", undefined, {options})\n // support channel(\"messaging\", \"\", {options})\n if (!channelIDOrCustom) {\n return new Channel<StreamChatGenerics>(this, channelType, undefined, custom);\n }\n\n return this.getChannelById(channelType, channelIDOrCustom, custom);\n }\n\n /**\n * It's a helper method for `client.channel()` method, used to create unique conversation or\n * channel based on member list instead of id.\n *\n * If the channel already exists in `activeChannels` list, then we simply return it, since that\n * means the same channel was already requested or created.\n *\n * Otherwise we create a new instance of Channel class and return it.\n *\n * @private\n *\n * @param {string} channelType The channel type\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n getChannelByMembers = (channelType: string, custom: ChannelData<StreamChatGenerics>) => {\n // Check if the channel already exists.\n // Only allow 1 channel object per cid\n const membersStr = [...(custom.members || [])].sort().join(',');\n const tempCid = `${channelType}:!members-${membersStr}`;\n\n if (!membersStr) {\n throw Error('Please specify atleast one member when creating unique conversation');\n }\n\n // channel could exist in `activeChannels` list with either one of the following two keys:\n // 1. cid - Which gets set on channel only after calling channel.query or channel.watch or channel.create\n // 2. Sorted membersStr - E.g., \"messaging:amin,vishal\" OR \"messaging:amin,jaap,tom\"\n // This is set when you create a channel, but haven't queried yet. After query,\n // we will replace it with `cid`\n for (const key in this.activeChannels) {\n const channel = this.activeChannels[key];\n if (channel.disconnected) {\n continue;\n }\n\n if (key === tempCid) {\n return channel;\n }\n\n if (key.indexOf(`${channelType}:!members-`) === 0) {\n const membersStrInExistingChannel = Object.keys(channel.state.members).sort().join(',');\n if (membersStrInExistingChannel === membersStr) {\n return channel;\n }\n }\n }\n\n const channel = new Channel<StreamChatGenerics>(this, channelType, undefined, custom);\n\n // For the time being set the key as membersStr, since we don't know the cid yet.\n // In channel.query, we will replace it with 'cid'.\n this.activeChannels[tempCid] = channel;\n return channel;\n };\n\n /**\n * Its a helper method for `client.channel()` method, used to channel given the id of channel.\n *\n * If the channel already exists in `activeChannels` list, then we simply return it, since that\n * means the same channel was already requested or created.\n *\n * Otherwise we create a new instance of Channel class and return it.\n *\n * @private\n *\n * @param {string} channelType The channel type\n * @param {string} [channelID] The channel ID\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n getChannelById = (channelType: string, channelID: string, custom: ChannelData<StreamChatGenerics>) => {\n if (typeof channelID === 'string' && ~channelID.indexOf(':')) {\n throw Error(`Invalid channel id ${channelID}, can't contain the : character`);\n }\n\n // only allow 1 channel object per cid\n const cid = `${channelType}:${channelID}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = { ...channel.data, ...custom };\n channel._data = { ...channel._data, ...custom };\n }\n return channel;\n }\n const channel = new Channel<StreamChatGenerics>(this, channelType, channelID, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n /**\n * partialUpdateUser - Update the given user object\n *\n * @param {PartialUserUpdate<StreamChatGenerics>} partialUserObject which should contain id and any of \"set\" or \"unset\" params;\n * example: {id: \"user1\", set:{field: value}, unset:[\"field2\"]}\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>} list of updated users\n */\n async partialUpdateUser(partialUserObject: PartialUserUpdate<StreamChatGenerics>) {\n return await this.partialUpdateUsers([partialUserObject]);\n }\n\n /**\n * upsertUsers - Batch upsert the list of users\n *\n * @param {UserResponse<StreamChatGenerics>[]} users list of users\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n async upsertUsers(users: UserResponse<StreamChatGenerics>[]) {\n const userMap: { [key: string]: UserResponse<StreamChatGenerics> } = {};\n for (const userObject of users) {\n if (!userObject.id) {\n throw Error('User ID is required when updating a user');\n }\n userMap[userObject.id] = userObject;\n }\n\n return await this.post<\n APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n }\n >(this.baseURL + '/users', { users: userMap });\n }\n\n /**\n * @deprecated Please use upsertUsers() function instead.\n *\n * updateUsers - Batch update the list of users\n *\n * @param {UserResponse<StreamChatGenerics>[]} users list of users\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n updateUsers = this.upsertUsers;\n\n /**\n * upsertUser - Update or Create the given user object\n *\n * @param {UserResponse<StreamChatGenerics>} userObject user object, the only required field is the user id. IE {id: \"myuser\"} is valid\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n upsertUser(userObject: UserResponse<StreamChatGenerics>) {\n return this.upsertUsers([userObject]);\n }\n\n /**\n * @deprecated Please use upsertUser() function instead.\n *\n * updateUser - Update or Create the given user object\n *\n * @param {UserResponse<StreamChatGenerics>} userObject user object, the only required field is the user id. IE {id: \"myuser\"} is valid\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n updateUser = this.upsertUser;\n\n /**\n * partialUpdateUsers - Batch partial update of users\n *\n * @param {PartialUserUpdate<StreamChatGenerics>[]} users list of partial update requests\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n async partialUpdateUsers(users: PartialUserUpdate<StreamChatGenerics>[]) {\n for (const userObject of users) {\n if (!userObject.id) {\n throw Error('User ID is required when updating a user');\n }\n }\n\n return await this.patch<\n APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n }\n >(this.baseURL + '/users', { users });\n }\n\n async deleteUser(\n userID: string,\n params?: {\n delete_conversation_channels?: boolean;\n hard_delete?: boolean;\n mark_messages_deleted?: boolean;\n },\n ) {\n return await this.delete<\n APIResponse & { user: UserResponse<StreamChatGenerics> } & {\n task_id?: string;\n }\n >(this.baseURL + `/users/${encodeURIComponent(userID)}`, params);\n }\n\n /**\n * restoreUsers - Restore soft deleted users\n *\n * @param {string[]} user_ids which users to restore\n *\n * @return {APIResponse} An API response\n */\n async restoreUsers(user_ids: string[]) {\n return await this.post<APIResponse>(this.baseURL + `/users/restore`, {\n user_ids,\n });\n }\n\n /**\n * reactivateUser - Reactivate one user\n *\n * @param {string} userID which user to reactivate\n * @param {ReactivateUserOptions} [options]\n *\n * @return {UserResponse} Reactivated user\n */\n async reactivateUser(userID: string, options?: ReactivateUserOptions) {\n return await this.post<APIResponse & { user: UserResponse<StreamChatGenerics> }>(\n this.baseURL + `/users/${encodeURIComponent(userID)}/reactivate`,\n { ...options },\n );\n }\n\n /**\n * reactivateUsers - Reactivate many users asynchronously\n *\n * @param {string[]} user_ids which users to reactivate\n * @param {ReactivateUsersOptions} [options]\n *\n * @return {TaskResponse} A task ID\n */\n async reactivateUsers(user_ids: string[], options?: ReactivateUsersOptions) {\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/reactivate`, { user_ids, ...options });\n }\n\n /**\n * deactivateUser - Deactivate one user\n *\n * @param {string} userID which user to deactivate\n * @param {DeactivateUsersOptions} [options]\n *\n * @return {UserResponse} Deactivated user\n */\n async deactivateUser(userID: string, options?: DeactivateUsersOptions) {\n return await this.post<APIResponse & { user: UserResponse<StreamChatGenerics> }>(\n this.baseURL + `/users/${encodeURIComponent(userID)}/deactivate`,\n { ...options },\n );\n }\n\n /**\n * deactivateUsers - Deactivate many users asynchronously\n *\n * @param {string[]} user_ids which users to deactivate\n * @param {DeactivateUsersOptions} [options]\n *\n * @return {TaskResponse} A task ID\n */\n async deactivateUsers(user_ids: string[], options?: DeactivateUsersOptions) {\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/deactivate`, { user_ids, ...options });\n }\n\n async exportUser(userID: string, options?: Record<string, string>) {\n return await this.get<\n APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n reactions: ReactionResponse<StreamChatGenerics>[];\n user: UserResponse<StreamChatGenerics>;\n }\n >(this.baseURL + `/users/${encodeURIComponent(userID)}/export`, { ...options });\n }\n\n /** banUser - bans a user from all channels\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<APIResponse>}\n */\n async banUser(targetUserID: string, options?: BanUserOptions<StreamChatGenerics>) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/ban', {\n target_user_id: targetUserID,\n ...options,\n });\n }\n\n /** unbanUser - revoke global ban for a user\n *\n * @param {string} targetUserID\n * @param {UnBanUserOptions} [options]\n * @returns {Promise<APIResponse>}\n */\n async unbanUser(targetUserID: string, options?: UnBanUserOptions) {\n return await this.delete<APIResponse>(this.baseURL + '/moderation/ban', {\n target_user_id: targetUserID,\n ...options,\n });\n }\n\n /** shadowBan - shadow bans a user from all channels\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<APIResponse>}\n */\n async shadowBan(targetUserID: string, options?: BanUserOptions<StreamChatGenerics>) {\n return await this.banUser(targetUserID, {\n shadow: true,\n ...options,\n });\n }\n\n /** removeShadowBan - revoke global shadow ban for a user\n *\n * @param {string} targetUserID\n * @param {UnBanUserOptions} [options]\n * @returns {Promise<APIResponse>}\n */\n async removeShadowBan(targetUserID: string, options?: UnBanUserOptions) {\n return await this.unbanUser(targetUserID, {\n shadow: true,\n ...options,\n });\n }\n async blockUser(blockedUserID: string, user_id?: string) {\n return await this.post<BlockUserAPIResponse>(this.baseURL + '/users/block', {\n blocked_user_id: blockedUserID,\n ...(user_id ? { user_id } : {}),\n });\n }\n\n async getBlockedUsers(user_id?: string) {\n return await this.get<GetBlockedUsersAPIResponse>(this.baseURL + '/users/block', {\n ...(user_id ? { user_id } : {}),\n });\n }\n async unBlockUser(blockedUserID: string, userID?: string) {\n return await this.post<APIResponse>(this.baseURL + '/users/unblock', {\n blocked_user_id: blockedUserID,\n ...(userID ? { user_id: userID } : {}),\n });\n }\n /** muteUser - mutes a user\n *\n * @param {string} targetID\n * @param {string} [userID] Only used with serverside auth\n * @param {MuteUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<MuteUserResponse<StreamChatGenerics>>}\n */\n async muteUser(targetID: string, userID?: string, options: MuteUserOptions<StreamChatGenerics> = {}) {\n return await this.post<MuteUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/mute', {\n target_id: targetID,\n ...(userID ? { user_id: userID } : {}),\n ...options,\n });\n }\n\n /** unmuteUser - unmutes a user\n *\n * @param {string} targetID\n * @param {string} [currentUserID] Only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unmuteUser(targetID: string, currentUserID?: string) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/unmute', {\n target_id: targetID,\n ...(currentUserID ? { user_id: currentUserID } : {}),\n });\n }\n\n /** userMuteStatus - check if a user is muted or not, can be used after connectUser() is called\n *\n * @param {string} targetID\n * @returns {boolean}\n */\n userMuteStatus(targetID: string) {\n if (!this.user || !this.wsPromise) {\n throw new Error('Make sure to await connectUser() first.');\n }\n\n for (let i = 0; i < this.mutedUsers.length; i += 1) {\n if (this.mutedUsers[i].target.id === targetID) return true;\n }\n return false;\n }\n\n /**\n * flagMessage - flag a message\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async flagMessage(targetMessageID: string, options: { reason?: string; user_id?: string } = {}) {\n return await this.post<FlagMessageResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flag', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n\n /**\n * flagUser - flag a user\n * @param {string} targetID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async flagUser(targetID: string, options: { reason?: string; user_id?: string } = {}) {\n return await this.post<FlagUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flag', {\n target_user_id: targetID,\n ...options,\n });\n }\n\n /**\n * unflagMessage - unflag a message\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unflagMessage(targetMessageID: string, options: { user_id?: string } = {}) {\n return await this.post<FlagMessageResponse<StreamChatGenerics>>(this.baseURL + '/moderation/unflag', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n\n /**\n * unflagUser - unflag a user\n * @param {string} targetID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unflagUser(targetID: string, options: { user_id?: string } = {}) {\n return await this.post<FlagUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/unflag', {\n target_user_id: targetID,\n ...options,\n });\n }\n\n /**\n * getCallToken - retrieves the auth token needed to join a call\n *\n * @param {string} callID\n * @param {object} options\n * @returns {Promise<GetCallTokenResponse>}\n */\n async getCallToken(callID: string, options: { user_id?: string } = {}) {\n return await this.post<GetCallTokenResponse>(this.baseURL + `/calls/${encodeURIComponent(callID)}`, { ...options });\n }\n\n /**\n * _queryFlags - Query flags.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {FlagsFilters} filterConditions MongoDB style filter conditions\n * @param {FlagsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<FlagsResponse<StreamChatGenerics>>} Flags Response\n */\n async _queryFlags(filterConditions: FlagsFilters = {}, options: FlagsPaginationOptions = {}) {\n // Return a list of flags\n return await this.post<FlagsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flags', {\n filter_conditions: filterConditions,\n ...options,\n });\n }\n\n /**\n * _queryFlagReports - Query flag reports.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {FlagReportsFilters} filterConditions MongoDB style filter conditions\n * @param {FlagReportsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<FlagReportsResponse<StreamChatGenerics>>} Flag Reports Response\n */\n async _queryFlagReports(filterConditions: FlagReportsFilters = {}, options: FlagReportsPaginationOptions = {}) {\n // Return a list of message flags\n return await this.post<FlagReportsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/reports', {\n filter_conditions: filterConditions,\n ...options,\n });\n }\n\n /**\n * _reviewFlagReport - review flag report\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} [id] flag report to review\n * @param {string} [reviewResult] flag report review result\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @param {string} [options.review_details] custom information about review result\n * @returns {Promise<ReviewFlagReportResponse>>}\n */\n async _reviewFlagReport(id: string, reviewResult: string, options: ReviewFlagReportOptions = {}) {\n return await this.patch<ReviewFlagReportResponse<StreamChatGenerics>>(\n this.baseURL + `/moderation/reports/${encodeURIComponent(id)}`,\n {\n review_result: reviewResult,\n ...options,\n },\n );\n }\n\n /**\n * unblockMessage - unblocks message blocked by automod\n *\n *\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unblockMessage(targetMessageID: string, options: { user_id?: string } = {}) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/unblock_message', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n // alias for backwards compatibility\n _unblockMessage = this.unblockMessage;\n\n /**\n * @deprecated use markChannelsRead instead\n *\n * markAllRead - marks all channels for this user as read\n * @param {MarkAllReadOptions<StreamChatGenerics>} [data]\n *\n * @return {Promise<APIResponse>}\n */\n markAllRead = this.markChannelsRead;\n\n /**\n * markChannelsRead - marks channels read -\n * it accepts a map of cid:messageid pairs, if messageid is empty, the whole channel will be marked as read\n *\n * @param {MarkChannelsReadOptions <StreamChatGenerics>} [data]\n *\n * @return {Promise<APIResponse>}\n */\n async markChannelsRead(data: MarkChannelsReadOptions<StreamChatGenerics> = {}) {\n await this.post<APIResponse>(this.baseURL + '/channels/read', { ...data });\n }\n\n createCommand(data: CreateCommandOptions<StreamChatGenerics>) {\n return this.post<CreateCommandResponse<StreamChatGenerics>>(this.baseURL + '/commands', data);\n }\n\n getCommand(name: string) {\n return this.get<GetCommandResponse<StreamChatGenerics>>(this.baseURL + `/commands/${encodeURIComponent(name)}`);\n }\n\n updateCommand(name: string, data: UpdateCommandOptions<StreamChatGenerics>) {\n return this.put<UpdateCommandResponse<StreamChatGenerics>>(\n this.baseURL + `/commands/${encodeURIComponent(name)}`,\n data,\n );\n }\n\n deleteCommand(name: string) {\n return this.delete<DeleteCommandResponse<StreamChatGenerics>>(\n this.baseURL + `/commands/${encodeURIComponent(name)}`,\n );\n }\n\n listCommands() {\n return this.get<ListCommandsResponse<StreamChatGenerics>>(this.baseURL + `/commands`);\n }\n\n createChannelType(data: CreateChannelOptions<StreamChatGenerics>) {\n const channelData = Object.assign({}, { commands: ['all'] }, data);\n return this.post<CreateChannelResponse<StreamChatGenerics>>(this.baseURL + '/channeltypes', channelData);\n }\n\n getChannelType(channelType: string) {\n return this.get<GetChannelTypeResponse<StreamChatGenerics>>(\n this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`,\n );\n }\n\n updateChannelType(channelType: string, data: UpdateChannelOptions<StreamChatGenerics>) {\n return this.put<UpdateChannelResponse<StreamChatGenerics>>(\n this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`,\n data,\n );\n }\n\n deleteChannelType(channelType: string) {\n return this.delete<APIResponse>(this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`);\n }\n\n listChannelTypes() {\n return this.get<ListChannelResponse<StreamChatGenerics>>(this.baseURL + `/channeltypes`);\n }\n\n /**\n * translateMessage - adds the translation to the message\n *\n * @param {string} messageId\n * @param {string} language\n *\n * @return {MessageResponse<StreamChatGenerics>} Response that includes the message\n */\n async translateMessage(messageId: string, language: string) {\n return await this.post<APIResponse & MessageResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageId)}/translate`,\n { language },\n );\n }\n\n /**\n * _normalizeExpiration - transforms expiration value into ISO string\n * @param {undefined|null|number|string|Date} timeoutOrExpirationDate expiration date or timeout. Use number type to set timeout in seconds, string or Date to set exact expiration date\n */\n _normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {\n let pinExpires: null | string = null;\n if (typeof timeoutOrExpirationDate === 'number') {\n const now = new Date();\n now.setSeconds(now.getSeconds() + timeoutOrExpirationDate);\n pinExpires = now.toISOString();\n } else if (isString(timeoutOrExpirationDate)) {\n pinExpires = timeoutOrExpirationDate;\n } else if (timeoutOrExpirationDate instanceof Date) {\n pinExpires = timeoutOrExpirationDate.toISOString();\n }\n return pinExpires;\n }\n\n /**\n * _messageId - extracts string message id from either message object or message id\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {string} errorText error message to report in case of message id absence\n */\n _validateAndGetMessageId(messageOrMessageId: string | { id: string }, errorText: string) {\n let messageId: string;\n if (typeof messageOrMessageId === 'string') {\n messageId = messageOrMessageId;\n } else {\n if (!messageOrMessageId.id) {\n throw Error(errorText);\n }\n messageId = messageOrMessageId.id;\n }\n return messageId;\n }\n\n /**\n * pinMessage - pins the message\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {undefined|null|number|string|Date} timeoutOrExpirationDate expiration date or timeout. Use number type to set timeout in seconds, string or Date to set exact expiration date\n * @param {undefined|string | { id: string }} [pinnedBy] who will appear as a user who pinned a message. Only for server-side use. Provide `undefined` when pinning message client-side\n * @param {undefined|number|string|Date} pinnedAt date when message should be pinned. It affects the order of pinned messages. Use negative number to set relative time in the past, string or Date to set exact date of pin\n */\n pinMessage(\n messageOrMessageId: string | { id: string },\n timeoutOrExpirationDate?: null | number | string | Date,\n pinnedBy?: string | { id: string },\n pinnedAt?: number | string | Date,\n ) {\n const messageId = this._validateAndGetMessageId(\n messageOrMessageId,\n 'Please specify the message id when calling unpinMessage',\n );\n return this.partialUpdateMessage(\n messageId,\n ({\n set: {\n pinned: true,\n pin_expires: this._normalizeExpiration(timeoutOrExpirationDate),\n pinned_at: this._normalizeExpiration(pinnedAt),\n },\n } as unknown) as PartialMessageUpdate<StreamChatGenerics>,\n pinnedBy,\n );\n }\n\n /**\n * unpinMessage - unpins the message that was previously pinned\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {string | { id: string }} [userId]\n */\n unpinMessage(messageOrMessageId: string | { id: string }, userId?: string | { id: string }) {\n const messageId = this._validateAndGetMessageId(\n messageOrMessageId,\n 'Please specify the message id when calling unpinMessage',\n );\n return this.partialUpdateMessage(\n messageId,\n ({\n set: { pinned: false },\n } as unknown) as PartialMessageUpdate<StreamChatGenerics>,\n userId,\n );\n }\n\n /**\n * updateMessage - Update the given message\n *\n * @param {Omit<MessageResponse<StreamChatGenerics>, 'mentioned_users'> & { mentioned_users?: string[] }} message object, id needs to be specified\n * @param {string | { id: string }} [userId]\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the message\n */\n async updateMessage(\n message: UpdatedMessage<StreamChatGenerics>,\n userId?: string | { id: string },\n options?: UpdateMessageOptions,\n ) {\n if (!message.id) {\n throw Error('Please specify the message id when calling updateMessage');\n }\n\n const clonedMessage: Message = Object.assign({}, message);\n delete clonedMessage.id;\n\n const reservedMessageFields: Array<ReservedMessageFields> = [\n 'command',\n 'created_at',\n 'html',\n 'latest_reactions',\n 'own_reactions',\n 'quoted_message',\n 'reaction_counts',\n 'reply_count',\n 'type',\n 'updated_at',\n 'user',\n '__html',\n ];\n\n reservedMessageFields.forEach(function (item) {\n if (clonedMessage[item] != null) {\n delete clonedMessage[item];\n }\n });\n\n if (userId != null) {\n if (isString(userId)) {\n clonedMessage.user_id = userId;\n } else {\n clonedMessage.user = {\n id: userId.id,\n } as UserResponse<StreamChatGenerics>;\n }\n }\n\n /**\n * Server always expects mentioned_users to be array of string. We are adding extra check, just in case\n * SDK missed this conversion.\n */\n if (Array.isArray(clonedMessage.mentioned_users) && !isString(clonedMessage.mentioned_users[0])) {\n clonedMessage.mentioned_users = clonedMessage.mentioned_users.map((mu) => ((mu as unknown) as UserResponse).id);\n }\n\n return await this.post<UpdateMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(message.id as string)}`,\n {\n message: clonedMessage,\n ...options,\n },\n );\n }\n\n /**\n * partialUpdateMessage - Update the given message id while retaining additional properties\n *\n * @param {string} id the message id\n *\n * @param {PartialUpdateMessage<StreamChatGenerics>} partialMessageObject which should contain id and any of \"set\" or \"unset\" params;\n * example: {id: \"user1\", set:{text: \"hi\"}, unset:[\"color\"]}\n * @param {string | { id: string }} [userId]\n *\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the updated message\n */\n async partialUpdateMessage(\n id: string,\n partialMessageObject: PartialMessageUpdate<StreamChatGenerics>,\n userId?: string | { id: string },\n options?: UpdateMessageOptions,\n ) {\n if (!id) {\n throw Error('Please specify the message id when calling partialUpdateMessage');\n }\n let user = userId;\n if (userId != null && isString(userId)) {\n user = { id: userId };\n }\n return await this.put<UpdateMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(id)}`,\n {\n ...partialMessageObject,\n ...options,\n user,\n },\n );\n }\n\n async deleteMessage(messageID: string, hardDelete?: boolean) {\n let params = {};\n if (hardDelete) {\n params = { hard: true };\n }\n return await this.delete<APIResponse & { message: MessageResponse<StreamChatGenerics> }>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}`,\n params,\n );\n }\n\n /**\n * undeleteMessage - Undelete a message\n *\n * undeletes a message that was previous soft deleted. Hard deleted messages\n * cannot be undeleted. This is only allowed to be called from server-side\n * clients.\n *\n * @param {string} messageID The id of the message to undelete\n * @param {string} userID The id of the user who undeleted the message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the message\n */\n async undeleteMessage(messageID: string, userID: string) {\n return await this.post<APIResponse & { message: MessageResponse<StreamChatGenerics> }>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}/undelete`,\n { undeleted_by: userID },\n );\n }\n\n async getMessage(messageID: string, options?: GetMessageOptions) {\n return await this.get<GetMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}`,\n { ...options },\n );\n }\n\n /**\n * queryThreads - returns the list of threads of current user.\n *\n * @param {QueryThreadsOptions} options Options object for pagination and limiting the participants and replies.\n * @param {number} options.limit Limits the number of threads to be returned.\n * @param {boolean} options.watch Subscribes the user to the channels of the threads.\n * @param {number} options.participant_limit Limits the number of participants returned per threads.\n * @param {number} options.reply_limit Limits the number of replies returned per threads.\n *\n * @returns {{ threads: Thread<StreamChatGenerics>[], next: string }} Returns the list of threads and the next cursor.\n */\n async queryThreads(options?: QueryThreadsOptions) {\n const opts = {\n limit: 10,\n participant_limit: 10,\n reply_limit: 3,\n watch: true,\n ...options,\n };\n\n const res = await this.post<QueryThreadsAPIResponse<StreamChatGenerics>>(this.baseURL + `/threads`, opts);\n\n return {\n threads: res.threads.map((thread) => new Thread({ client: this, threadData: thread })),\n next: res.next,\n };\n }\n\n /**\n * getThread - returns the thread of a message by its id.\n *\n * @param {string} messageId The message id\n * @param {GetThreadOptions} options Options object for pagination and limiting the participants and replies.\n * @param {boolean} options.watch Subscribes the user to the channel of the thread.\n * @param {number} options.participant_limit Limits the number of participants returned per threads.\n * @param {number} options.reply_limit Limits the number of replies returned per threads.\n *\n * @returns {Thread<StreamChatGenerics>} Returns the thread.\n */\n async getThread(messageId: string, options: GetThreadOptions = {}) {\n if (!messageId) {\n throw Error('Please specify the message id when calling partialUpdateThread');\n }\n\n const opts = {\n participant_limit: 100,\n reply_limit: 3,\n watch: true,\n ...options,\n };\n\n const res = await this.get<GetThreadAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/threads/${encodeURIComponent(messageId)}`,\n opts,\n );\n\n return new Thread<StreamChatGenerics>({ client: this, threadData: res.thread });\n }\n\n /**\n * partialUpdateThread - updates the given thread\n *\n * @param {string} messageId The id of the thread message which needs to be updated.\n * @param {PartialThreadUpdate} partialThreadObject should contain \"set\" or \"unset\" params for any of the thread's non-reserved fields.\n *\n * @returns {GetThreadAPIResponse<StreamChatGenerics>} Returns the updated thread.\n */\n async partialUpdateThread(messageId: string, partialThreadObject: PartialThreadUpdate) {\n if (!messageId) {\n throw Error('Please specify the message id when calling partialUpdateThread');\n }\n\n // check for reserved fields from ThreadResponse type within partialThreadObject's set and unset.\n // Throw error if any of the reserved field is found.\n const reservedThreadFields = [\n 'created_at',\n 'id',\n 'last_message_at',\n 'type',\n 'updated_at',\n 'user',\n 'reply_count',\n 'participants',\n 'channel',\n ];\n\n for (const key in { ...partialThreadObject.set, ...partialThreadObject.unset }) {\n if (reservedThreadFields.includes(key)) {\n throw Error(\n `You cannot set ${key} field on Thread object. ${key} is reserved for server-side use. Please omit ${key} from your set object.`,\n );\n }\n }\n\n return await this.patch<GetThreadAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/threads/${encodeURIComponent(messageId)}`,\n partialThreadObject,\n );\n }\n\n getUserAgent() {\n return (\n this.userAgent || `stream-chat-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n\n /**\n * _isUsingServerAuth - Returns true if we're using server side auth\n */\n _isUsingServerAuth = () => !!this.secret;\n\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n const token = this._getToken();\n const authorization = token ? { Authorization: token } : undefined;\n let signal: AbortSignal | null = null;\n if (this.nextRequestAbortController !== null) {\n signal = this.nextRequestAbortController.signal;\n this.nextRequestAbortController = null;\n }\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n\n const { params: axiosRequestConfigParams, headers: axiosRequestConfigHeaders, ...axiosRequestConfigRest } =\n this.options.axiosRequestConfig || {};\n\n return {\n params: {\n user_id: this.userID,\n connection_id: this._getConnectionID(),\n api_key: this.key,\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n },\n headers: {\n ...authorization,\n 'stream-auth-type': this.getAuthType(),\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n ...(signal ? { signal } : {}),\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n _getToken() {\n if (!this.tokenManager || this.anonymous) return null;\n\n return this.tokenManager.getToken();\n }\n\n _startCleaning() {\n const that = this;\n if (this.cleaningIntervalRef != null) {\n return;\n }\n this.cleaningIntervalRef = setInterval(() => {\n // call clean on the channel, used for calling the stop.typing event etc.\n for (const channel of Object.values(that.activeChannels)) {\n channel.clean();\n }\n }, 500);\n }\n\n /**\n * encode ws url payload\n * @private\n * @returns json string\n */\n _buildWSPayload = (client_request_id?: string) => {\n return JSON.stringify({\n user_id: this.userID,\n user_details: this._user,\n device: this.options.device,\n client_request_id,\n });\n };\n\n /**\n * checks signature of a request\n * @param {string | Buffer} rawBody\n * @param {string} signature from HTTP header\n * @returns {boolean}\n */\n verifyWebhook(requestBody: string | Buffer, xSignature: string) {\n return !!this.secret && CheckSignature(requestBody, this.secret, xSignature);\n }\n\n /** getPermission - gets the definition for a permission\n *\n * @param {string} name\n * @returns {Promise<PermissionAPIResponse>}\n */\n getPermission(name: string) {\n return this.get<PermissionAPIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(name)}`);\n }\n\n /** createPermission - creates a custom permission\n *\n * @param {CustomPermissionOptions} permissionData the permission data\n * @returns {Promise<APIResponse>}\n */\n createPermission(permissionData: CustomPermissionOptions) {\n return this.post<APIResponse>(`${this.baseURL}/permissions`, {\n ...permissionData,\n });\n }\n\n /** updatePermission - updates an existing custom permission\n *\n * @param {string} id\n * @param {Omit<CustomPermissionOptions, 'id'>} permissionData the permission data\n * @returns {Promise<APIResponse>}\n */\n updatePermission(id: string, permissionData: Omit<CustomPermissionOptions, 'id'>) {\n return this.put<APIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(id)}`, {\n ...permissionData,\n });\n }\n\n /** deletePermission - deletes a custom permission\n *\n * @param {string} name\n * @returns {Promise<APIResponse>}\n */\n deletePermission(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(name)}`);\n }\n\n /** listPermissions - returns the list of all permissions for this application\n *\n * @returns {Promise<APIResponse>}\n */\n listPermissions() {\n return this.get<PermissionsAPIResponse>(`${this.baseURL}/permissions`);\n }\n\n /** createRole - creates a custom role\n *\n * @param {string} name the new role name\n * @returns {Promise<APIResponse>}\n */\n createRole(name: string) {\n return this.post<APIResponse>(`${this.baseURL}/roles`, { name });\n }\n\n /** listRoles - returns the list of all roles for this application\n *\n * @returns {Promise<APIResponse>}\n */\n listRoles() {\n return this.get<APIResponse>(`${this.baseURL}/roles`);\n }\n\n /** deleteRole - deletes a custom role\n *\n * @param {string} name the role name\n * @returns {Promise<APIResponse>}\n */\n deleteRole(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/roles/${encodeURIComponent(name)}`);\n }\n\n /** sync - returns all events that happened for a list of channels since last sync\n * @param {string[]} channel_cids list of channel CIDs\n * @param {string} last_sync_at last time the user was online and in sync. RFC3339 ie. \"2020-05-06T15:05:01.207Z\"\n * @param {SyncOptions} options See JSDoc in the type fields for more info\n *\n * @returns {Promise<SyncResponse>}\n */\n sync(channel_cids: string[], last_sync_at: string, options: SyncOptions = {}) {\n return this.post<SyncResponse>(`${this.baseURL}/sync`, {\n channel_cids,\n last_sync_at,\n ...options,\n });\n }\n\n /**\n * sendUserCustomEvent - Send a custom event to a user\n *\n * @param {string} targetUserID target user id\n * @param {UserCustomEvent} event for example {type: 'friendship-request'}\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async sendUserCustomEvent(targetUserID: string, event: UserCustomEvent) {\n return await this.post<APIResponse>(`${this.baseURL}/users/${encodeURIComponent(targetUserID)}/event`, {\n event,\n });\n }\n\n createBlockList(blockList: BlockList) {\n return this.post<APIResponse>(`${this.baseURL}/blocklists`, blockList);\n }\n\n listBlockLists() {\n return this.get<APIResponse & { blocklists: BlockListResponse[] }>(`${this.baseURL}/blocklists`);\n }\n\n getBlockList(name: string) {\n return this.get<APIResponse & { blocklist: BlockListResponse }>(\n `${this.baseURL}/blocklists/${encodeURIComponent(name)}`,\n );\n }\n\n updateBlockList(name: string, data: { words: string[] }) {\n return this.put<APIResponse>(`${this.baseURL}/blocklists/${encodeURIComponent(name)}`, data);\n }\n\n deleteBlockList(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/blocklists/${encodeURIComponent(name)}`);\n }\n\n exportChannels(request: Array<ExportChannelRequest>, options: ExportChannelOptions = {}) {\n const payload = { channels: request, ...options };\n return this.post<APIResponse & ExportChannelResponse>(`${this.baseURL}/export_channels`, payload);\n }\n\n exportUsers(request: ExportUsersRequest) {\n return this.post<APIResponse & ExportUsersResponse>(`${this.baseURL}/export/users`, request);\n }\n\n exportChannel(request: ExportChannelRequest, options?: ExportChannelOptions) {\n return this.exportChannels([request], options);\n }\n\n getExportChannelStatus(id: string) {\n return this.get<APIResponse & ExportChannelStatusResponse>(\n `${this.baseURL}/export_channels/${encodeURIComponent(id)}`,\n );\n }\n\n campaign(idOrData: string | CampaignData, data?: CampaignData) {\n if (idOrData && typeof idOrData === 'object') {\n return new Campaign(this, null, idOrData);\n }\n\n return new Campaign(this, idOrData, data);\n }\n\n segment(type: SegmentType, idOrData: string | SegmentData, data?: SegmentData) {\n if (typeof idOrData === 'string') {\n return new Segment(this, type, idOrData, data);\n }\n\n return new Segment(this, type, null, idOrData);\n }\n\n validateServerSideAuth() {\n if (!this.secret) {\n throw new Error(\n 'Campaigns is a server-side only feature. Please initialize the client with a secret to use this feature.',\n );\n }\n }\n\n /**\n * createSegment - Creates a segment\n *\n * @private\n * @param {SegmentType} type Segment type\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} params Segment data\n *\n * @return {{segment: SegmentResponse} & APIResponse} The created Segment\n */\n async createSegment(type: SegmentType, id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n const body = {\n id,\n type,\n ...data,\n };\n return this.post<{ segment: SegmentResponse }>(this.baseURL + `/segments`, body);\n }\n\n /**\n * createUserSegment - Creates a user segment\n *\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} data Segment data\n *\n * @return {Segment} The created Segment\n */\n async createUserSegment(id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n return this.createSegment('user', id, data);\n }\n\n /**\n * createChannelSegment - Creates a channel segment\n *\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} data Segment data\n *\n * @return {Segment} The created Segment\n */\n async createChannelSegment(id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n return this.createSegment('channel', id, data);\n }\n\n async getSegment(id: string) {\n this.validateServerSideAuth();\n return this.get<{ segment: SegmentResponse } & APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}`);\n }\n\n /**\n * updateSegment - Update a segment\n *\n * @param {string} id Segment ID\n * @param {Partial<UpdateSegmentData>} data Data to update\n *\n * @return {Segment} Updated Segment\n */\n async updateSegment(id: string, data: Partial<UpdateSegmentData>) {\n this.validateServerSideAuth();\n return this.put<{ segment: SegmentResponse }>(this.baseURL + `/segments/${encodeURIComponent(id)}`, data);\n }\n\n /**\n * addSegmentTargets - Add targets to a segment\n *\n * @param {string} id Segment ID\n * @param {string[]} targets Targets to add to the segment\n *\n * @return {APIResponse} API response\n */\n async addSegmentTargets(id: string, targets: string[]) {\n this.validateServerSideAuth();\n const body = { target_ids: targets };\n return this.post<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}/addtargets`, body);\n }\n\n async querySegmentTargets(\n id: string,\n filter: QuerySegmentTargetsFilter | null = {},\n sort: SortParam[] | null | [] = [],\n options = {},\n ) {\n this.validateServerSideAuth();\n return this.post<{ targets: SegmentTargetsResponse[]; next?: string } & APIResponse>(\n this.baseURL + `/segments/${encodeURIComponent(id)}/targets/query`,\n {\n filter: filter || {},\n sort: sort || [],\n ...options,\n },\n );\n }\n /**\n * removeSegmentTargets - Remove targets from a segment\n *\n * @param {string} id Segment ID\n * @param {string[]} targets Targets to add to the segment\n *\n * @return {APIResponse} API response\n */\n async removeSegmentTargets(id: string, targets: string[]) {\n this.validateServerSideAuth();\n const body = { target_ids: targets };\n return this.post<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}/deletetargets`, body);\n }\n\n /**\n * querySegments - Query Segments\n *\n * @param {filter} filter MongoDB style filter conditions\n * @param {QuerySegmentsOptions} options Options for sorting/paginating the results\n *\n * @return {Segment[]} Segments\n */\n async querySegments(filter: {}, sort?: SortParam[], options: QuerySegmentsOptions = {}) {\n this.validateServerSideAuth();\n return this.post<\n {\n segments: SegmentResponse[];\n next?: string;\n prev?: string;\n } & APIResponse\n >(this.baseURL + `/segments/query`, {\n filter,\n sort,\n ...options,\n });\n }\n\n /**\n * deleteSegment - Delete a Campaign Segment\n *\n * @param {string} id Segment ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async deleteSegment(id: string) {\n this.validateServerSideAuth();\n return this.delete<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}`);\n }\n\n /**\n * segmentTargetExists - Check if a target exists in a segment\n *\n * @param {string} segmentId Segment ID\n * @param {string} targetId Target ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async segmentTargetExists(segmentId: string, targetId: string) {\n this.validateServerSideAuth();\n return this.get<APIResponse>(\n this.baseURL + `/segments/${encodeURIComponent(segmentId)}/target/${encodeURIComponent(targetId)}`,\n );\n }\n\n /**\n * createCampaign - Creates a Campaign\n *\n * @param {CampaignData} params Campaign data\n *\n * @return {Campaign} The Created Campaign\n */\n async createCampaign(params: CampaignData) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns`, { ...params });\n }\n\n async getCampaign(id: string) {\n this.validateServerSideAuth();\n return this.get<{ campaign: CampaignResponse } & APIResponse>(\n this.baseURL + `/campaigns/${encodeURIComponent(id)}`,\n );\n }\n\n async startCampaign(id: string, options?: { scheduledFor?: string; stopAt?: string }) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse } & APIResponse>(\n this.baseURL + `/campaigns/${encodeURIComponent(id)}/start`,\n {\n scheduled_for: options?.scheduledFor,\n stop_at: options?.stopAt,\n },\n );\n }\n /**\n * queryCampaigns - Query Campaigns\n *\n *\n * @return {Campaign[]} Campaigns\n */\n async queryCampaigns(filter: CampaignFilters, sort?: CampaignSort, options?: CampaignQueryOptions) {\n this.validateServerSideAuth();\n return await this.post<\n {\n campaigns: CampaignResponse[];\n next?: string;\n prev?: string;\n } & APIResponse\n >(this.baseURL + `/campaigns/query`, {\n filter,\n sort,\n ...(options || {}),\n });\n }\n\n /**\n * updateCampaign - Update a Campaign\n *\n * @param {string} id Campaign ID\n * @param {Partial<CampaignData>} params Campaign data\n *\n * @return {Campaign} Updated Campaign\n */\n async updateCampaign(id: string, params: Partial<CampaignData>) {\n this.validateServerSideAuth();\n return this.put<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`, params);\n }\n\n /**\n * deleteCampaign - Delete a Campaign\n *\n * @param {string} id Campaign ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async deleteCampaign(id: string) {\n this.validateServerSideAuth();\n return this.delete<APIResponse>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`);\n }\n\n /**\n * stopCampaign - Stop a Campaign\n *\n * @param {string} id Campaign ID\n *\n * @return {Campaign} Stopped Campaign\n */\n async stopCampaign(id: string) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}/stop`);\n }\n\n /**\n * enrichURL - Get OpenGraph data of the given link\n *\n * @param {string} url link\n * @return {OGAttachment} OG Attachment\n */\n async enrichURL(url: string) {\n return this.get<APIResponse & OGAttachment>(this.baseURL + `/og`, { url });\n }\n\n /**\n * getTask - Gets status of a long running task\n *\n * @param {string} id Task ID\n *\n * @return {TaskStatus} The task status\n */\n async getTask(id: string) {\n return this.get<APIResponse & TaskStatus>(`${this.baseURL}/tasks/${encodeURIComponent(id)}`);\n }\n\n /**\n * deleteChannels - Deletes a list of channel\n *\n * @param {string[]} cids Channel CIDs\n * @param {boolean} [options.hard_delete] Defines if the channel is hard deleted or not\n *\n * @return {DeleteChannelsResponse} Result of the soft deletion, if server-side, it holds the task ID as well\n */\n async deleteChannels(cids: string[], options: { hard_delete?: boolean } = {}) {\n return await this.post<APIResponse & DeleteChannelsResponse>(this.baseURL + `/channels/delete`, {\n cids,\n ...options,\n });\n }\n\n /**\n * deleteUsers - Batch Delete Users\n *\n * @param {string[]} user_ids which users to delete\n * @param {DeleteUserOptions} options Configuration how to delete users\n *\n * @return {TaskResponse} A task ID\n */\n async deleteUsers(user_ids: string[], options: DeleteUserOptions = {}) {\n if (typeof options.user !== 'undefined' && !['soft', 'hard', 'pruning'].includes(options.user)) {\n throw new Error('Invalid delete user options. user must be one of [soft hard pruning]');\n }\n if (typeof options.conversations !== 'undefined' && !['soft', 'hard'].includes(options.conversations)) {\n throw new Error('Invalid delete user options. conversations must be one of [soft hard]');\n }\n if (typeof options.messages !== 'undefined' && !['soft', 'hard', 'pruning'].includes(options.messages)) {\n throw new Error('Invalid delete user options. messages must be one of [soft hard pruning]');\n }\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/delete`, {\n user_ids,\n ...options,\n });\n }\n\n /**\n * _createImportURL - Create an Import upload url.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} filename filename of uploaded data\n * @return {APIResponse & CreateImportResponse} An ImportTask\n */\n async _createImportURL(filename: string) {\n return await this.post<APIResponse & CreateImportURLResponse>(this.baseURL + `/import_urls`, {\n filename,\n });\n }\n\n /**\n * _createImport - Create an Import Task.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} path path of uploaded data\n * @param {CreateImportOptions} options import options\n * @return {APIResponse & CreateImportResponse} An ImportTask\n */\n async _createImport(path: string, options: CreateImportOptions = { mode: 'upsert' }) {\n return await this.post<APIResponse & CreateImportResponse>(this.baseURL + `/imports`, {\n path,\n ...options,\n });\n }\n\n /**\n * _getImport - Get an Import Task.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} id id of Import Task\n *\n * @return {APIResponse & GetImportResponse} An ImportTask\n */\n async _getImport(id: string) {\n return await this.get<APIResponse & GetImportResponse>(this.baseURL + `/imports/${encodeURIComponent(id)}`);\n }\n\n /**\n * _listImports - Lists Import Tasks.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {ListImportsPaginationOptions} options pagination options\n *\n * @return {APIResponse & ListImportsResponse} An ImportTask\n */\n async _listImports(options: ListImportsPaginationOptions) {\n return await this.get<APIResponse & ListImportsResponse>(this.baseURL + `/imports`, options);\n }\n\n /**\n * upsertPushProvider - Create or Update a push provider\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @param {PushProviderConfig} configuration of the provider you want to create or update\n *\n * @return {APIResponse & PushProviderUpsertResponse} A push provider\n */\n async upsertPushProvider(pushProvider: PushProviderConfig) {\n return await this.post<APIResponse & PushProviderUpsertResponse>(this.baseURL + `/push_providers`, {\n push_provider: pushProvider,\n });\n }\n\n /**\n * deletePushProvider - Delete a push provider\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @param {PushProviderID} type and foreign id of the push provider to be deleted\n *\n * @return {APIResponse} An API response\n */\n async deletePushProvider({ type, name }: PushProviderID) {\n return await this.delete<APIResponse>(\n this.baseURL + `/push_providers/${encodeURIComponent(type)}/${encodeURIComponent(name)}`,\n );\n }\n\n /**\n * listPushProviders - Get all push providers in the app\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @return {APIResponse & PushProviderListResponse} A push provider\n */\n async listPushProviders() {\n return await this.get<APIResponse & PushProviderListResponse>(this.baseURL + `/push_providers`);\n }\n\n /**\n * creates an abort controller that will be used by the next HTTP Request.\n */\n createAbortControllerForNextRequest() {\n return (this.nextRequestAbortController = new AbortController());\n }\n\n /**\n * commits a pending message, making it visible in the channel and for other users\n * @param id the message id\n *\n * @return {APIResponse & MessageResponse} The message\n */\n async commitMessage(id: string) {\n return await this.post<APIResponse & MessageResponse>(this.baseURL + `/messages/${encodeURIComponent(id)}/commit`);\n }\n\n /**\n * Creates a poll\n * @param poll PollData The poll that will be created\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & CreatePollAPIResponse} The poll\n */\n async createPoll(poll: CreatePollData<StreamChatGenerics>, userId?: string) {\n return await this.post<APIResponse & CreatePollAPIResponse<StreamChatGenerics>>(this.baseURL + `/polls`, {\n ...poll,\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Retrieves a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & GetPollAPIResponse} The poll\n */\n async getPoll(id: string, userId?: string): Promise<APIResponse & GetPollAPIResponse<StreamChatGenerics>> {\n return await this.get<APIResponse & GetPollAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(id)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Updates a poll\n * @param poll PollData The poll that will be updated\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollResponse} The poll\n */\n async updatePoll(poll: PollData<StreamChatGenerics>, userId?: string) {\n return await this.put<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>>(this.baseURL + `/polls`, {\n ...poll,\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Partially updates a poll\n * @param id string The poll id\n * @param {PartialPollUpdate<StreamChatGenerics>} partialPollObject which should contain id and any of \"set\" or \"unset\" params;\n * @param userId string The user id (only serverside)\n * example: {id: \"44f26af5-f2be-4fa7-9dac-71cf893781de\", set:{field: value}, unset:[\"field2\"]}\n * @returns {APIResponse & UpdatePollAPIResponse} The poll\n */\n async partialUpdatePoll(\n id: string,\n partialPollObject: PartialPollUpdate<StreamChatGenerics>,\n userId?: string,\n ): Promise<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>> {\n return await this.patch<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(id)}`,\n {\n ...partialPollObject,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Delete a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns\n */\n async deletePoll(id: string, userId?: string): Promise<APIResponse> {\n return await this.delete<APIResponse>(this.baseURL + `/polls/${encodeURIComponent(id)}`, {\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Close a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & UpdatePollAPIResponse} The poll\n */\n async closePoll(id: string, userId?: string): Promise<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>> {\n return this.partialUpdatePoll(\n id,\n {\n set: {\n is_closed: true,\n } as PartialPollUpdate<StreamChatGenerics>['set'],\n },\n userId,\n );\n }\n\n /**\n * Creates a poll option\n * @param pollId string The poll id\n * @param option PollOptionData The poll option that will be created\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollOptionResponse} The poll option\n */\n async createPollOption(pollId: string, option: PollOptionData<StreamChatGenerics>, userId?: string) {\n return await this.post<APIResponse & CreatePollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options`,\n {\n ...option,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Retrieves a poll option\n * @param pollId string The poll id\n * @param optionId string The poll option id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollOptionResponse} The poll option\n */\n async getPollOption(pollId: string, optionId: string, userId?: string) {\n return await this.get<APIResponse & GetPollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options/${encodeURIComponent(optionId)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Updates a poll option\n * @param pollId string The poll id\n * @param option PollOptionData The poll option that will be updated\n * @param userId string The user id (only serverside)\n * @returns\n */\n async updatePollOption(pollId: string, option: PollOptionData<StreamChatGenerics>, userId?: string) {\n return await this.put<APIResponse & UpdatePollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options`,\n {\n ...option,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Delete a poll option\n * @param pollId string The poll id\n * @param optionId string The poll option id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse} The poll option\n */\n async deletePollOption(pollId: string, optionId: string, userId?: string) {\n return await this.delete<APIResponse>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options/${encodeURIComponent(optionId)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Cast vote on a poll\n * @param messageId string The message id\n * @param pollId string The poll id\n * @param vote PollVoteData The vote that will be casted\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & CastVoteAPIResponse} The poll vote\n */\n async castPollVote(messageId: string, pollId: string, vote: PollVoteData, userId?: string) {\n return await this.post<APIResponse & CastVoteAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageId)}/polls/${encodeURIComponent(pollId)}/vote`,\n {\n vote,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Add a poll answer\n * @param messageId string The message id\n * @param pollId string The poll id\n * @param answerText string The answer text\n * @param userId string The user id (only serverside)\n */\n async addPollAnswer(messageId: string, pollId: string, answerText: string, userId?: string) {\n return this.castPollVote(\n messageId,\n pollId,\n {\n answer_text: answerText,\n },\n userId,\n );\n }\n\n async removePollVote(messageId: string, pollId: string, voteId: string, userId?: string) {\n return await this.delete<APIResponse & { vote: PollVote }>(\n this.baseURL +\n `/messages/${encodeURIComponent(messageId)}/polls/${encodeURIComponent(pollId)}/vote/${encodeURIComponent(\n voteId,\n )}`,\n {\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Queries polls\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & QueryPollsResponse} The polls\n */\n async queryPolls(\n filter: QueryPollsFilters = {},\n sort: PollSort = [],\n options: QueryPollsOptions = {},\n userId?: string,\n ): Promise<APIResponse & QueryPollsResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & QueryPollsResponse<StreamChatGenerics>>(this.baseURL + `/polls/query${q}`, {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n });\n }\n\n /**\n * Queries poll votes\n * @param pollId\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollVotesAPIResponse} The poll votes\n */\n async queryPollVotes(\n pollId: string,\n filter: QueryVotesFilters = {},\n sort: VoteSort = [],\n options: QueryVotesOptions = {},\n userId?: string,\n ): Promise<APIResponse & PollVotesAPIResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & PollVotesAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/votes${q}`,\n {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * Queries poll answers\n * @param pollId\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollAnswersAPIResponse} The poll votes\n */\n async queryPollAnswers(\n pollId: string,\n filter: QueryVotesFilters = {},\n sort: VoteSort = [],\n options: QueryVotesOptions = {},\n userId?: string,\n ): Promise<APIResponse & PollAnswersAPIResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & PollAnswersAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/votes${q}`,\n {\n filter: { ...filter, is_answer: true },\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * Query message history\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10}\n * @returns {APIResponse & QueryMessageHistoryResponse} The message histories\n */\n async queryMessageHistory(\n filter: QueryMessageHistoryFilters = {},\n sort: QueryMessageHistorySort = [],\n options: QueryMessageHistoryOptions = {},\n ): Promise<APIResponse & QueryMessageHistoryResponse<StreamChatGenerics>> {\n return await this.post<APIResponse & QueryMessageHistoryResponse<StreamChatGenerics>>(\n this.baseURL + '/messages/history',\n {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * updateFlags - reviews/unflags flagged message\n *\n * @param {string[]} message_ids list of message IDs\n * @param {string} options Option object in case user ID is set to review all the flagged messages by the user\n * @param {string} reviewed_by user ID who reviewed the flagged message\n * @returns {APIResponse}\n */\n async updateFlags(message_ids: string[], reviewed_by: string, options: { user_id?: string } = {}) {\n return await this.post<APIResponse>(this.baseURL + '/automod/v1/moderation/update_flags', {\n message_ids,\n reviewed_by,\n ...options,\n });\n }\n}\n","export default null;","import { PermissionObject } from './types';\n\ntype RequiredPermissionObject = Required<PermissionObject>;\n\nexport const Allow = 'Allow';\nexport const Deny = 'Deny';\nexport const AnyResource = ['*'];\nexport const AnyRole = ['*'];\nexport const MaxPriority = 999;\nexport const MinPriority = 1;\n\n// deprecated permission object class, you should use the new permission system v2 and use permissions\n// defined in BuiltinPermissions to configure your channel types\n\nexport class Permission {\n name: RequiredPermissionObject['name'];\n action: RequiredPermissionObject['action'];\n owner: RequiredPermissionObject['owner'];\n priority: RequiredPermissionObject['priority'];\n resources: RequiredPermissionObject['resources'];\n roles: RequiredPermissionObject['roles'];\n constructor(\n name: string,\n priority: number,\n resources = AnyResource,\n roles = AnyRole,\n owner = false,\n action: RequiredPermissionObject['action'] = Allow,\n ) {\n this.name = name;\n this.action = action;\n this.owner = owner;\n this.priority = priority;\n this.resources = resources;\n this.roles = roles;\n }\n}\n\n// deprecated\nexport const AllowAll = new Permission('Allow all', MaxPriority, AnyResource, AnyRole, false, Allow);\n\n// deprecated\nexport const DenyAll = new Permission('Deny all', MinPriority, AnyResource, AnyRole, false, Deny);\n\nexport type Role = 'admin' | 'user' | 'guest' | 'anonymous' | 'channel_member' | 'channel_moderator' | string;\n\nexport const BuiltinRoles = {\n Admin: 'admin',\n Anonymous: 'anonymous',\n ChannelMember: 'channel_member',\n ChannelModerator: 'channel_moderator',\n Guest: 'guest',\n User: 'user',\n};\n\nexport const BuiltinPermissions = {\n AddLinks: 'Add Links',\n BanUser: 'Ban User',\n CreateChannel: 'Create Channel',\n CreateMessage: 'Create Message',\n CreateReaction: 'Create Reaction',\n DeleteAnyAttachment: 'Delete Any Attachment',\n DeleteAnyChannel: 'Delete Any Channel',\n DeleteAnyMessage: 'Delete Any Message',\n DeleteAnyReaction: 'Delete Any Reaction',\n DeleteOwnAttachment: 'Delete Own Attachment',\n DeleteOwnChannel: 'Delete Own Channel',\n DeleteOwnMessage: 'Delete Own Message',\n DeleteOwnReaction: 'Delete Own Reaction',\n ReadAnyChannel: 'Read Any Channel',\n ReadOwnChannel: 'Read Own Channel',\n RunMessageAction: 'Run Message Action',\n UpdateAnyChannel: 'Update Any Channel',\n UpdateAnyMessage: 'Update Any Message',\n UpdateMembersAnyChannel: 'Update Members Any Channel',\n UpdateMembersOwnChannel: 'Update Members Own Channel',\n UpdateOwnChannel: 'Update Own Channel',\n UpdateOwnMessage: 'Update Own Message',\n UploadAttachment: 'Upload Attachment',\n UseFrozenChannel: 'Send messages and reactions to frozen channels',\n};\n","export const EVENT_MAP = {\n 'channel.created': true,\n 'channel.deleted': true,\n 'channel.hidden': true,\n 'channel.kicked': true,\n 'channel.muted': true,\n 'channel.truncated': true,\n 'channel.unmuted': true,\n 'channel.updated': true,\n 'channel.visible': true,\n 'health.check': true,\n 'member.added': true,\n 'member.removed': true,\n 'member.updated': true,\n 'message.deleted': true,\n 'message.new': true,\n 'message.read': true,\n 'message.updated': true,\n 'message.undeleted': true,\n 'notification.added_to_channel': true,\n 'notification.channel_deleted': true,\n 'notification.channel_mutes_updated': true,\n 'notification.channel_truncated': true,\n 'notification.invite_accepted': true,\n 'notification.invite_rejected': true,\n 'notification.invited': true,\n 'notification.mark_read': true,\n 'notification.mark_unread': true,\n 'notification.message_new': true,\n 'notification.mutes_updated': true,\n 'notification.removed_from_channel': true,\n 'notification.thread_message_new': true,\n 'poll.closed': true,\n 'poll.updated': true,\n 'poll.vote_casted': true,\n 'poll.vote_changed': true,\n 'poll.vote_removed': true,\n 'reaction.deleted': true,\n 'reaction.new': true,\n 'reaction.updated': true,\n 'typing.start': true,\n 'typing.stop': true,\n 'user.banned': true,\n 'user.deleted': true,\n 'user.presence.changed': true,\n 'user.unbanned': true,\n 'user.unread_message_reminder': true,\n 'user.updated': true,\n 'user.watching.start': true,\n 'user.watching.stop': true,\n\n // local events\n 'channels.queried': true,\n 'connection.changed': true,\n 'connection.recovered': true,\n 'transport.changed': true,\n 'capabilities.changed': true,\n};\n"],"names":["uint8","tmp","len","length","extraBytes","parts","maxChunkLength","i","len2","push","encodeChunk","lookup","join","revLookup","code","charCodeAt","start","end","num","output","isString","arrayOrString","isMapStringCallback","callback","encodeBase64","data","fromByteArray","Uint8Array","res","k","charAt","mappedValue","map","char","decodeBase64","s","x","a","e","w","String","fromCharCode","L","b","l","r","asyncGeneratorStep","gen","resolve","reject","_next","_throw","key","arg","info","value","error","done","Promise","then","_asyncToGenerator","fn","self","this","args","arguments","apply","err","undefined","_classCallCheck","instance","Constructor","TypeError","_defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","_createClass","protoProps","staticProps","prototype","_defineProperty","obj","runtime","exports","Op","hasOwn","hasOwnProperty","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","define","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","state","GenStateSuspendedStart","method","GenStateExecuting","Error","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","type","GenStateSuspendedYield","makeInvokeMethod","call","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","defineIteratorMethods","forEach","AsyncIterator","PromiseImpl","invoke","result","__await","unwrapped","previousPromise","callInvokeWithMethodAndArg","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","constructor","displayName","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","async","iter","toString","keys","object","reverse","pop","skipTempReset","prev","slice","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","catch","thrown","delegateYield","module","regeneratorRuntime","accidentalStrictMode","Function","require$$0","Campaign","client","id","body","message_template","_this$data","segment_ids","_this$data2","sender_id","_this$data3","channel_template","_this$data4","create_channels","_this$data5","description","_this$data6","_this$data7","user_ids","_this$data8","createCampaign","campaign","options","verifyCampaignId","startCampaign","updateCampaign","deleteCampaign","stopCampaign","getCampaign","_extends","assign","source","_typeof","_objectWithoutProperties","excluded","sourceKeys","indexOf","objectWithoutPropertiesLoose","getOwnPropertySymbols","sourceSymbolKeys","propertyIsEnumerable","_arrayLikeToArray","arr","arr2","Array","_unsupportedIterableToArray","o","minLen","arrayLikeToArray","n","from","test","_toConsumableArray","isArray","arrayWithoutHoles","iterableToArray","unsupportedIterableToArray","nonIterableSpread","bind","thisArg","kindOf","cache","thing","str","toLowerCase","kindOfTest","typeOfTest","isUndefined","isArrayBuffer","isFunction","isNumber","isObject","isPlainObject","val","isDate","isFile","isBlob","isFileList","isURLSearchParams","allOwnKeys","getOwnPropertyNames","findKey","_key","_global","globalThis","window","global","isContextDefined","isTypedArray","TypedArray","isHTMLForm","prop","isRegExp","reduceDescriptors","reducer","descriptors","getOwnPropertyDescriptors","reducedDescriptors","ret","defineProperties","ALPHA","DIGIT","ALPHABET","ALPHA_DIGIT","toUpperCase","isAsyncFn","isBuffer","isFormData","kind","FormData","append","isArrayBufferView","ArrayBuffer","isView","buffer","isBoolean","isStream","pipe","merge","caseless","assignValue","targetKey","extend","trim","replace","stripBOM","content","inherits","superConstructor","toFlatObject","sourceObj","destObj","filter","propFilter","merged","endsWith","searchString","position","lastIndex","toArray","forEachEntry","pair","matchAll","regExp","matches","exec","hasOwnProp","freezeMethods","set","toObjectSet","delimiter","split","toCamelCase","m","p1","p2","noop","toFiniteNumber","defaultValue","Number","isFinite","generateString","size","alphabet","Math","random","isSpecCompliantForm","toJSONObject","stack","visit","reducedValue","isThenable","AxiosError","message","config","request","response","captureStackTrace","utils","toJSON","number","fileName","lineNumber","columnNumber","status","customProps","axiosError","cause","isVisitable","removeBrackets","renderKey","path","dots","concat","token","predicates","toFormData","formData","metaTokens","indexes","option","visitor","defaultVisitor","useBlob","Blob","convertValue","toISOString","Buffer","JSON","stringify","some","isFlatArray","el","index","exposedHelpers","build","encode","charMap","encodeURIComponent","match","AxiosURLSearchParams","params","_pairs","buildURL","url","_encode","serializeFn","serialize","serializedParams","hashmarkIndex","encoder","InterceptorManager","handlers","use","fulfilled","rejected","synchronous","runWhen","eject","clear","h","silentJSONParsing","forcedJSONParsing","clarifyTimeoutError","isBrowser","classes","URLSearchParams","isStandardBrowserEnv","product","navigator","document","isStandardBrowserWebWorkerEnv","WorkerGlobalScope","importScripts","protocols","formDataToJSON","buildPath","isNumericKey","isLast","arrayToObject","entries","parsePropPath","defaults","transitional","transitionalDefaults","adapter","transformRequest","headers","contentType","getContentType","hasJSONContentType","isObjectPayload","setContentType","platform","helpers","toURLEncodedForm","formSerializer","_FormData","env","rawValue","parser","parse","stringifySafely","transformResponse","JSONRequested","responseType","strictJSONParsing","ERR_BAD_RESPONSE","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","common","Accept","ignoreDuplicateOf","$internals","normalizeHeader","header","normalizeValue","matchHeaderValue","isHeaderNameFilter","AxiosHeaders","valueOrRewrite","rewrite","setHeader","_value","_header","_rewrite","lHeader","setHeaders","rawHeaders","parsed","line","substring","parseHeaders","get","tokens","tokensRE","parseTokens","has","matcher","delete","deleted","deleteHeader","normalize","format","normalized","formatHeader","targets","asStrings","static","first","computed","accessors","defineAccessor","accessorName","methodName","arg1","arg2","arg3","buildAccessors","transformData","fns","isCancel","__CANCEL__","CanceledError","ERR_CANCELED","accessor","mapped","headerValue","write","expires","domain","secure","cookie","Date","toGMTString","read","RegExp","decodeURIComponent","remove","now","buildFullPath","baseURL","requestedURL","relativeURL","combineURLs","msie","userAgent","urlParsingNode","createElement","originURL","resolveURL","href","setAttribute","protocol","host","search","hash","hostname","port","pathname","location","requestURL","progressEventReducer","listener","isDownloadStream","bytesNotified","_speedometer","samplesCount","min","bytes","timestamps","firstSampleTS","head","tail","chunkLength","startedAt","bytesCount","passed","round","speedometer","loaded","total","lengthComputable","progressBytes","rate","progress","estimated","event","knownAdapters","http","xhr","XMLHttpRequest","requestData","requestHeaders","onCanceled","cancelToken","unsubscribe","signal","removeEventListener","auth","username","password","unescape","btoa","fullPath","onloadend","responseHeaders","getAllResponseHeaders","ERR_BAD_REQUEST","floor","settle","responseText","statusText","open","paramsSerializer","onreadystatechange","readyState","responseURL","setTimeout","onabort","ECONNABORTED","onerror","ERR_NETWORK","ontimeout","timeoutErrorMessage","ETIMEDOUT","xsrfValue","isURLSameOrigin","cookies","setRequestHeader","withCredentials","onDownloadProgress","addEventListener","onUploadProgress","upload","cancel","abort","subscribe","aborted","parseProtocol","send","renderReason","reason","isResolvedHandle","adapters","nameOrAdapter","rejectedReasons","reasons","throwIfCancellationRequested","throwIfRequested","dispatchRequest","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","timeoutMessage","decompress","beforeRedirect","transport","httpAgent","httpsAgent","socketPath","responseEncoding","configValue","VERSION","validators","deprecatedWarnings","validator","version","formatMessage","opt","desc","opts","ERR_DEPRECATED","console","warn","assertOptions","schema","allowUnknown","ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","Axios","instanceConfig","interceptors","configOrUrl","boolean","function","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","interceptor","unshift","responseInterceptorChain","promise","chain","newConfig","onFulfilled","onRejected","getUri","generateHTTPMethod","isForm","CancelToken","executor","resolvePromise","_listeners","onfulfilled","_resolve","splice","c","HttpStatusCode","Continue","SwitchingProtocols","Processing","EarlyHints","Ok","Created","Accepted","NonAuthoritativeInformation","NoContent","ResetContent","PartialContent","MultiStatus","AlreadyReported","ImUsed","MultipleChoices","MovedPermanently","Found","SeeOther","NotModified","UseProxy","Unused","TemporaryRedirect","PermanentRedirect","BadRequest","Unauthorized","PaymentRequired","Forbidden","NotFound","MethodNotAllowed","NotAcceptable","ProxyAuthenticationRequired","RequestTimeout","Conflict","Gone","LengthRequired","PreconditionFailed","PayloadTooLarge","UriTooLong","UnsupportedMediaType","RangeNotSatisfiable","ExpectationFailed","ImATeapot","MisdirectedRequest","UnprocessableEntity","Locked","FailedDependency","TooEarly","UpgradeRequired","PreconditionRequired","TooManyRequests","RequestHeaderFieldsTooLarge","UnavailableForLegalReasons","InternalServerError","NotImplemented","BadGateway","ServiceUnavailable","GatewayTimeout","HttpVersionNotSupported","VariantAlsoNegotiates","InsufficientStorage","LoopDetected","NotExtended","NetworkAuthenticationRequired","axios","createInstance","defaultConfig","Cancel","all","promises","spread","isAxiosError","payload","formToJSON","getAdapter","default","_slicedToArray","arrayWithHoles","_i","_s","_e","_arr","_n","_d","iterableToArrayLimit","nonIterableRest","logChatPromiseExecution","sleep","chatCodes","TOKEN_EXPIRED","WS_CLOSED_SUCCESS","addFileToFormData","uri","readable","_read","File","isFileWebAPI","isBlobWebAPI","normalizeQuerySort","sort","sortFields","item","field","direction","retryInterval","numberOfFailures","max","randomId","getRandomValues","getRandomBytes","hex","subarray","padStart","getRandomValuesWithMathRandom","pow","byteLength","crypto","_crypto","msCrypto","convertErrorToJson","jsonObj","getOwnPropertyDescriptor","_","addConnectionEventListeners","cb","removeConnectionEventListeners","axiosParamsSerializer","newParams","__html","html","pinned_at","created_at","updated_at","deleted_at","reaction_groups","maybeGetReactionGroupsFallback","reaction_counts","reaction_scores","findIndexInSortedArray","needle","sortedArray","selectValueToCompare","sortDirection","left","right","middle","comparableNeedle","comparableMiddle","addToMessageList","messages","newMessage","timestampChanged","sortBy","addIfDoesNotExist","addMessageToList","newMessages","messageTime","getTime","messageIsNewest","at","insertionIndex","groups","counts","scores","fallback","count","sum_scores","throttle","leading","trailing","runningTimeout","storedArgs","timeoutHandler","messagePaginationCreatedAtAround","hasPrev","hasNext","updateHasPrev","updateHasNext","parentSet","requestedPageSize","returnedPage","messagePaginationOptions","newPagination","pagination","created_at_around","createdAtAroundDate","firstPageMsg","lastPageMsg","wholePageHasNewerMessages","wholePageHasOlderMessages","requestedPageSizeNotMet","noMoreMessages","_parentSet$messages$","_parentSet$messages$s","midPointByCount","midPointByCreationDate","array","targetDate","mid","midCreatedAt","midDate","binarySearchByDateEqualOrNearestGreater","messageSetPagination","logger","_params$messagePagina","_params$messagePagina2","id_around","_parentSet$messages$2","_parentSet$messages$s2","midPoint","targetMsg","halves","find","messagePaginationIdAround","firstPageMsgIsFirstInSet","_parentSet$messages$3","lastPageMsgIsLastInSet","_parentSet$messages$s3","queriedNextMessages","created_at_after_or_equal","created_at_after","id_gt","id_gte","queriedPrevMessages","created_at_before_or_equal","created_at_before","id_lt","id_lte","offset","containsUnrecognizedOptionsOnly","hasMore","returnedPageIsEmpty","messagePaginationLinear","DEFAULT_MESSAGE_SET_PAGINATION","ChannelState","channel","isUpToDate","_this","msgArray","msg","removed","user","_updateUserMessages","parentId","messageSets","threads","pinnedMessages","hardDelete","_deleteUserMessages","cid","latest_reactions","mentioned_users","own_reactions","parent_id","reply_count","thread_participants","_channel","watcher_count","typing","initMessages","pending_messages","mutedUsers","watchers","members","membership","unreadCount","last_message_at","isCurrent","findIndex","isLatest","messageSetToAddToIfDoesNotExist","addMessagesSorted","initializing","findTargetMessageSet","messagesToAdd","targetMessageSetIndex","isFromShadowBannedUser","shadowed","isMessageFormatted","_this$_channel","getClient","updateUserReference","parentID","show_in_channel","_addToMessageList","thread","messageSet","addPinnedMessage","pinnedMessage","removeMessageFromArray","reaction","enforce_unique","messageWithReaction","_updateMessage","_this2","_addOwnReactionToMessage","ownReactions","_removeOwnReactionFromMessage","userID","user_id","_this3","update","updatedMessages","reduce","acc","quoted_message_id","_m$pinned_at","_m$updated_at","quoted_message","attachments","_this4","_updateQuotedMessageReferences","updateFunc","pinned","msgIndex","messageSetIndex","findMessageSetIndex","messageToRemove","isRemoved","threadMessages","filteredMessages","latestMessages","lastEvent","receivedAt","received_at","dispatchEvent","messageId","parentMessageId","limit","switchedToMessageSet","loadedMessageThread","messageIdToFind","switchToMessageSet","_this$threads$parentM","query","getReplies","currentMessages","messages1","messages2","m1","m2","overlappingMessageSetIndices","_this5","areMessageSetsOverlap","mergeTargetMessageSetIndex","mergeSourceMessageSetIndices","sources","overlappingMessageSetIndex","Channel","defaultOptions","watch","presence","listeners","_client","_data","initialized","offlineMode","lastTypingEvent","isTyping","disconnected","configs","post","_channelURL","sendFile","_checkInitialized","filter_conditions","message_filter_conditions","wsPromise","filterConditions","updates","patch","messageID","reactionType","channelData","updateMessage","_update","areCapabilitiesChanged","own_capabilities","coolDownInterval","cooldown","accept_invite","reject_invite","add_members","add_moderators","roles","assign_roles","invites","remove_members","demote_moderators","channel_cid","cli","uid","partialUpdateMember","archived","resp","channel_member","_muteStatus","message_id","form_data","_isTypingIndicatorsEnabled","diff","lastKeyStroke","sendEvent","getConfig","_this$getConfig","typing_events","_this$getClient$user","privacy_settings","_this$getClient$user$2","typing_indicators","_this$getClient$user$3","enabled","messageSlice","_this$getConfig2","read_events","_isUsingServerAuth","_this$getConfig3","stopTyping","clean","_hasConnectionID","combined","tags","normalizedSort","messageIds","ids","last_read","silent","userMuteStatus","includes","muteStatus","muted","lastRead","_countMessageAsUnread","_message$mentioned_us","queryURL","membersStr","member","_member$user","tempChannelCid","activeChannels","_addChannelConfig","_initializeState","_options$messages","polls","hydratePollCache","queriedChannels","channels","isLatestMessageSet","targetUserID","banUser","userId","clearHistory","clear_history","unbanUser","shadowBan","removeShadowBan","pollId","vote","castPollVote","voteId","removePollVote","callbackOrString","callbackOrNothing","channelState","_event$user","_event$user2","last_read_message_id","unread_messages","_this$getClient$user2","_event$user5","_event$user6","_extendEventWithOwnReactions","hard_delete","removeMessage","addMessageSorted","removeQuotedMessageReferences","removePinnedMessage","ownMessage","_this$getClient$user3","isThreadMessage","_event$user8","_event$channel","truncated_at","truncatedAt","createdAt","clearMessages","_event$member","_event$user9","newMembers","_this$getClient$user4","first_unread_message_id","last_read_at","frozen","_channel$data","hidden","_event$channel3","_channel$data2","_event$channel4","_channel$data3","addReaction","removeReaction","_event$user11","shadow_banned","shadow","banned","_event$user12","clientState","addPinnedMessages","pinned_messages","watcher","_hydrateMembers","findMessage","setIsUpToDate","ClientState","users","userChannelReferences","updateUser","channelID","ws","WebSocket","MozWebSocket","InsightMetrics","connectionStartTimestamp","wsTotalFailures","wsConsecutiveFailures","instanceClientId","postInsights","insightType","insights","maxAttempts","buildWsFatalInsight","connection","buildWsBaseInsight","ready_state","_connection$ws","_buildUrl","api_key","start_ts","insightMetrics","end_ts","auth_type","getAuthType","tokenManager","user_details","_user","device","client_id","connectionID","ws_details","ws_consecutive_failures","ws_total_failures","request_id","requestID","online","_navigator","onLine","user_agent","_navigator2","instance_client_id","buildWsSuccessAfterFailureInsight","isCloseEvent","isErrorEvent","StableWSConnection","qs","_buildWSPayload","getToken","wsBaseURL","getUserAgent","_log","_setHealth","isHealthy","_reconnect","interval","wsID","isResolved","rejectPromise","_errorFromWSEvent","scheduleNextPing","handleEvent","scheduleConnectionCheck","wasClean","consecutiveFailures","totalFailures","isConnecting","healthy","statusCode","isWSFailure","StatusCode","connectionOpen","healthCheckTimeoutRef","clearTimeout","clientID","pingInterval","connectionCheckTimeoutRef","connectionCheckTimeout","isDisconnected","onlineStatusChanged","extra","level","_connect","healthCheck","_context","isStatic","refreshToken","_waitForHealthy","race","_context2","isClosedPromise","clearInterval","removeAllListeners","close","OPEN","onclose","enableWSFallback","isTokenReady","tokenReady","loadToken","_setupConnectionPromise","wsURL","onopen","onmessage","connection_id","enableInsights","_destroyCurrentWSConnection","recoverState","_context6","JWTUserToken","apiSecret","extraData","JWTServerToken","jwtOptions","server","algorithm","noTimestamp","sign","UserFromToken","fragments","b64Payload","DevToken","CheckSignature","secret","signature","createHmac","digest","timingSafeEqual","ConnectionState","TokenManager","tokenOrProvider","validateToken","tokenProvider","loadTokenPromise","anon","tokenUserId","APIErrorCodes","retryable","isAPIError","isErrorRetryable","WSConnectionFallback","_setState","Closed","connect","retry","doAxiosRequest","_this$cancelToken2","_req","Connected","events","_data$events","Disconnected","reconnect","Connecting","json","_poll","_onlineStatusChanged","Init","Segment","all_sender_channels","all_users","createSegment","verifySegmentId","getSegment","updateSegment","addSegmentTargets","removeSegmentTargets","deleteSegment","targetId","segmentTargetExists","querySegmentTargets","_assertThisInitialized","ReferenceError","_setPrototypeOf","p","_possibleConstructorReturn","assertThisInitialized","_getPrototypeOf","_isNativeReflectConstruct","Reflect","construct","sham","Proxy","Boolean","valueOf","_construct","Parent","Class","isNativeReflectConstruct","_wrapNativeSuper","_cache","Map","isNativeFunction","Wrapper","VotingVisibility","ErrorFromResponse","subClass","superClass","StateStore","Set","newValueOrPatch","newValue","isPatch","oldValue","handlerSet","handler","partial","current","add","selector","selectedValues","nextValue","newlySelectedValues","hasUpdatedValues","logCount","oldSelectedValues","DEFAULT_PAGE_LIMIT","DEFAULT_SORT","Thread","threadData","partialNext","active","getLatestValue","isLoading","getThread","hydrateState","replyCount","replies","parentMessage","participants","deletedAt","updatedAt","pendingReplies","failedRepliesMap","isStateStale","unsubscribeFunctions","subscribeMarkActiveThreadRead","subscribeReloadActiveStaleThread","subscribeMarkThreadStale","subscribeNewReplies","subscribeRepliesRead","subscribeMessageDeleted","subscribeMessageUpdated","subscribeWithSelector","unreadMessageCount","ownUnreadCountSelector","throttledMarkAsRead","reload","on","isOwnMessage","upsertReplyLocally","nextRead","userRead","nextUserRead","lastReadAt","parent_message_id","lastReadMessageId","deleteReplyLocally","updateParentMessageLocally","eventType","updateParentMessageOrReplyLocally","cleanupFunction","reply","actualIndex","updatedReplies","formattedMessage","force","ownUnreadCount","markRead","thread_id","markAsRead","otherOptions","loadPage","loadingKey","cursorKey","insertionMethodKey","queryOptions","abs","queryReplies","maybeNextCursor","_replies$at","nextReplies","_context3","placeholderReadResponse","repliesPaginationFromInitialThread","parent_message","formatReadState","latest_replies","nextCursor","prevCursor","_thread$latest_replie2","isLoadingNext","isLoadingPrev","currentUserId","_state$read$currentUs","MODERATION_ENTITY_TYPES","Moderation","flaggedUserID","flag","entityType","entityId","entityCreatorID","entity_type","entity_id","entity_creator_id","targetID","target_ids","actionType","itemID","action_type","item_id","entityID","moderationPayload","configKey","moderation_payload","config_key","THREAD_MANAGER_INITIAL_STATE","isThreadOrderStale","unreadThreadCount","unseenThreadIds","lastConnectionDropAt","ready","ThreadManager","subscribeUnreadThreadsCountChange","subscribeManageThreadSubscriptions","subscribeReloadOnActivation","subscribeRecoverAfterConnectionDrop","subscribeChannelDeleted","unread_threads","me","newThreads","nextThreads","removedThreads","threadsById","registerSubscriptions","unregisterSubscriptions","_event$message","unsubscribeConnectionDropped","throttledHandleConnectionRecovered","unsubscribeConnectionRecovered","queryThreads","currentThreads","incomingThread","existingThread","hasStaleState","participant_limit","reply_limit","threadsByIdGetterCache","newThreadsById","isVoteAnswer","answer_text","Poll","poll","own_votes","pollResponseForState","voteOrAnswer","ownAnswer","ownVotes","lastActivityAt","maxVotedOptionIds","getMaxVotedOptionIds","vote_counts_by_option","ownVotesByOptionId","getOwnVotesByOptionId","getInitialStateFromPollResponse","pollData","extractPollData","is_closed","currentState","isOwnVote","poll_vote","latestAnswers","latest_answers","option_id","pollEnrichData","extractPollEnrichedData","answer","enforce_unique_votes","optionId","getPoll","updatePoll","partialPollObject","partialUpdatePoll","closePoll","deletePoll","createPollOption","updatePollOption","deletePollOption","max_votes_allowed","oldestVote","_oldestVote","_oldestVote2","removeVote","answerText","addPollAnswer","answerId","queryPollAnswers","queryPollVotes","voteCountsByOption","maxVotes","winningOptions","pollResponse","allow_answers","allow_user_suggested_options","enforce_unique_vote","voting_visibility","answers_count","latest_votes_by_option","vote_count","PollManager","pollCache","subscribeMessageNew","subscribePollUpdated","subscribePollClosed","subscribeVoteCasted","subscribeVoteChanged","subscribeVoteRemoved","createPoll","createdPoll","cachedPoll","fromState","setOrOverwriteInCache","queryPolls","pollInstances","overwriteState","pollFromCache","reinitializeState","_event$poll","handlePollUpdated","_event$poll2","handlePollClosed","_event$poll3","handleVoteCasted","_event$poll4","handleVoteChanged","_event$poll5","handleVoteRemoved","StreamChat","secretOrOptions","wsConnection","wsFallback","_this$wsFallback","_getConnectionID","userTokenOrProvider","setUserPromise","node","allowServerSideConnect","anonymous","setTokenPromise","_setToken","_setUser","openConnection","persistUserOnConnectionFailure","closeConnection","disconnectUser","connectUser","setTokenOrProvider","cleaningIntervalRef","_this$wsConnection2","disconnect","_this$wsFallback2","_this$wsFallback3","_startCleaning","before","closePromise","_disconnect","resetState","anonymousUser","_setupConnection","connectAnonymousUser","requestConfig","_enrichAxiosOptions","_logApiRequest","axiosInstance","postForm","put","_logApiResponse","handleResponse","client_request_id","_requestConfig$header","_logApiError","_context5","postListenerCallbacks","_handleClientEvent","_handleChannelEvent","_callClientListeners","_callChannelListeners","messageEvent","jsonString","refMap","_updateMemberWatcherReferences","updateUserMessages","deleteUserMessages","channel_mutes","devices","mutes","total_unread_count","unread_channels","unread_count","invisible","_updateUserMessageReferences","mark_messages_deleted","_deleteUserMessageReference","cids","recoverStateOnReconnect","queryChannels","$in","channelType","custom","tempCid","upsertUsers","upsertUser","unblockMessage","markChannelsRead","mutedChannels","moderation","inputOptions","browser","warmUp","Agent","keepAlive","keepAliveMsecs","setBaseURL","process","STREAM_LOCAL_TEST_RUN","STREAM_LOCAL_TEST_HOST","_this$options","defaultWSTimeoutWithFallback","defaultWSTimeout","apn_config","p12_cert","updateAppSettings","revoke_tokens_issued_before","_normalizeDate","revokeUsersToken","userIDs","partialUpdateUsers","apnTemplate","apn_template","firebaseTemplate","firebase_template","firebaseDataTemplate","firebase_data_template","skipDevices","skip_devices","pushProviderName","push_provider_name","pushProviderType","push_provider_type","last_active","guestUser","access_token","exp","iat","getHeaders","Infinity","errorFromResponse","_handleUserEvent","_event$me","_event$me2","activeChannelKey","deleteAllChannelReference","mute","expiresAt","_sayHi","setClient","nav","mode","updateUsers","stateOptions","hydrateActiveChannels","channelsFromApi","queryChannelsOptions","skipInitialization","updatedMessagesSet","message_limit","_this$wsFallback4","push_provider","serverSide","web","android","ios","endpoints","server_side","channelIDOrCustom","getChannelByMembers","_custom$members","getChannelById","partialUserObject","userMap","userObject","target_user_id","blockedUserID","blocked_user_id","target_id","currentUserID","targetMessageID","target_message_id","callID","reviewResult","review_result","commands","language","timeoutOrExpirationDate","pinExpires","setSeconds","getSeconds","messageOrMessageId","errorText","pinnedBy","pinnedAt","_validateAndGetMessageId","partialUpdateMessage","pin_expires","_normalizeExpiration","clonedMessage","mu","partialMessageObject","hard","undeleted_by","partialThreadObject","reservedThreadFields","unset","_getToken","authorization","Authorization","nextRequestAbortController","_options$headers","axiosRequestConfig","axiosRequestConfigParams","axiosRequestConfigHeaders","axiosRequestConfigRest","that","setInterval","requestBody","xSignature","permissionData","channel_cids","last_sync_at","blockList","exportChannels","idOrData","validateServerSideAuth","segmentId","scheduled_for","scheduledFor","stop_at","stopAt","conversations","filename","pushProvider","AbortController","q","is_answer","message_ids","reviewed_by","_instance","Allow","Deny","AnyResource","AnyRole","Permission","priority","resources","owner","action","AllowAll","DenyAll","AddLinks","BanUser","CreateChannel","CreateMessage","CreateReaction","DeleteAnyAttachment","DeleteAnyChannel","DeleteAnyMessage","DeleteAnyReaction","DeleteOwnAttachment","DeleteOwnChannel","DeleteOwnMessage","DeleteOwnReaction","ReadAnyChannel","ReadOwnChannel","RunMessageAction","UpdateAnyChannel","UpdateAnyMessage","UpdateMembersAnyChannel","UpdateMembersOwnChannel","UpdateOwnChannel","UpdateOwnMessage","UploadAttachment","UseFrozenChannel","Admin","Anonymous","ChannelMember","ChannelModerator","Guest","User"],"mappings":"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"}
1
+ {"version":3,"file":"browser.full-bundle.min.js","sources":["../node_modules/base64-js/index.js","../src/base64.ts","../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","../node_modules/@babel/runtime/helpers/esm/createClass.js","../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../node_modules/regenerator-runtime/runtime.js","../node_modules/@babel/runtime/regenerator/index.js","../src/campaign.ts","../node_modules/@babel/runtime/helpers/esm/extends.js","../node_modules/@babel/runtime/helpers/esm/typeof.js","../node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js","../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","../node_modules/axios/lib/helpers/bind.js","../node_modules/axios/lib/utils.js","../node_modules/axios/lib/core/AxiosError.js","../node_modules/axios/lib/helpers/toFormData.js","../node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../node_modules/axios/lib/helpers/buildURL.js","../node_modules/axios/lib/core/InterceptorManager.js","../node_modules/axios/lib/defaults/transitional.js","../node_modules/axios/lib/platform/browser/index.js","../node_modules/axios/lib/platform/browser/classes/URLSearchParams.js","../node_modules/axios/lib/platform/browser/classes/FormData.js","../node_modules/axios/lib/platform/browser/classes/Blob.js","../node_modules/axios/lib/helpers/formDataToJSON.js","../node_modules/axios/lib/defaults/index.js","../node_modules/axios/lib/helpers/toURLEncodedForm.js","../node_modules/axios/lib/helpers/parseHeaders.js","../node_modules/axios/lib/core/AxiosHeaders.js","../node_modules/axios/lib/core/transformData.js","../node_modules/axios/lib/cancel/isCancel.js","../node_modules/axios/lib/cancel/CanceledError.js","../node_modules/axios/lib/helpers/cookies.js","../node_modules/axios/lib/core/buildFullPath.js","../node_modules/axios/lib/helpers/isAbsoluteURL.js","../node_modules/axios/lib/helpers/combineURLs.js","../node_modules/axios/lib/helpers/isURLSameOrigin.js","../node_modules/axios/lib/adapters/xhr.js","../node_modules/axios/lib/helpers/speedometer.js","../node_modules/axios/lib/adapters/adapters.js","../node_modules/axios/lib/helpers/null.js","../node_modules/axios/lib/core/settle.js","../node_modules/axios/lib/helpers/parseProtocol.js","../node_modules/axios/lib/core/dispatchRequest.js","../node_modules/axios/lib/core/mergeConfig.js","../node_modules/axios/lib/env/data.js","../node_modules/axios/lib/helpers/validator.js","../node_modules/axios/lib/core/Axios.js","../node_modules/axios/lib/cancel/CancelToken.js","../node_modules/axios/lib/helpers/HttpStatusCode.js","../node_modules/axios/lib/axios.js","../node_modules/axios/lib/helpers/spread.js","../node_modules/axios/lib/helpers/isAxiosError.js","../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","../node_modules/form-data/lib/browser.js","../src/utils.ts","../src/constants.ts","../src/channel_state.ts","../src/channel.ts","../src/client_state.ts","../node_modules/isomorphic-ws/browser.js","../src/insights.ts","../src/connection.ts","../src/signing.ts","../jsonwebtoken","../crypto","../src/connection_fallback.ts","../src/token_manager.ts","../src/errors.ts","../src/segment.ts","../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js","../node_modules/@babel/runtime/helpers/esm/construct.js","../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js","../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js","../src/types.ts","../node_modules/@babel/runtime/helpers/esm/inherits.js","../src/store.ts","../src/thread.ts","../src/moderation.ts","../src/thread_manager.ts","../src/poll.ts","../src/poll_manager.ts","../src/client.ts","../https","../src/permissions.ts","../src/events.ts"],"sourcesContent":["'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n","import { fromByteArray } from 'base64-js';\n\nfunction isString<T>(arrayOrString: string | T[]): arrayOrString is string {\n return typeof (arrayOrString as string) === 'string';\n}\n\ntype MapGenericCallback<T, U> = (value: T, index: number, array: T[]) => U;\ntype MapStringCallback<U> = (value: string, index: number, string: string) => U;\n\nfunction isMapStringCallback<T, U>(\n arrayOrString: string | T[],\n callback: MapGenericCallback<T, U> | MapStringCallback<U>,\n): callback is MapStringCallback<U> {\n return !!callback && isString(arrayOrString);\n}\n\n// source - https://github.com/beatgammit/base64-js/blob/master/test/convert.js#L72\nfunction map<T, U>(array: T[], callback: MapGenericCallback<T, U>): U[];\nfunction map<U>(string: string, callback: MapStringCallback<U>): U[];\nfunction map<T, U>(arrayOrString: string | T[], callback: MapGenericCallback<T, U> | MapStringCallback<U>): U[] {\n const res = [];\n\n if (isString(arrayOrString) && isMapStringCallback(arrayOrString, callback)) {\n for (let k = 0, len = arrayOrString.length; k < len; k++) {\n if (arrayOrString.charAt(k)) {\n const kValue = arrayOrString.charAt(k);\n const mappedValue = callback(kValue, k, arrayOrString);\n res[k] = mappedValue;\n }\n }\n } else if (!isString(arrayOrString) && !isMapStringCallback(arrayOrString, callback)) {\n for (let k = 0, len = arrayOrString.length; k < len; k++) {\n if (k in arrayOrString) {\n const kValue = arrayOrString[k];\n const mappedValue = callback(kValue, k, arrayOrString);\n res[k] = mappedValue;\n }\n }\n }\n\n return res;\n}\n\nexport const encodeBase64 = (data: string): string =>\n fromByteArray(new Uint8Array(map(data, (char) => char.charCodeAt(0))));\n\n// base-64 decoder throws exception if encoded string is not padded by '=' to make string length\n// in multiples of 4. So gonna use our own method for this purpose to keep backwards compatibility\n// https://github.com/beatgammit/base64-js/blob/master/index.js#L26\nexport const decodeBase64 = (s: string): string => {\n const e = {} as { [key: string]: number },\n w = String.fromCharCode,\n L = s.length;\n let i,\n b = 0,\n c,\n x,\n l = 0,\n a,\n r = '';\n const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n for (i = 0; i < 64; i++) {\n e[A.charAt(i)] = i;\n }\n for (x = 0; x < L; x++) {\n c = e[s.charAt(x)];\n b = (b << 6) + c;\n l += 6;\n while (l >= 8) {\n ((a = (b >>> (l -= 8)) & 0xff) || x < L - 2) && (r += w(a));\n }\n }\n return r;\n};\n","function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n \"GeneratorFunction\"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, \"GeneratorFunction\");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n}\n","module.exports = require(\"regenerator-runtime\");\n","import { StreamChat } from './client';\nimport { CampaignData, DefaultGenerics, ExtendableGenerics } from './types';\n\nexport class Campaign<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n id: string | null;\n data?: CampaignData;\n client: StreamChat<StreamChatGenerics>;\n\n constructor(client: StreamChat<StreamChatGenerics>, id: string | null, data?: CampaignData) {\n this.client = client;\n this.id = id;\n this.data = data;\n }\n\n async create() {\n const body = {\n id: this.id,\n message_template: this.data?.message_template,\n segment_ids: this.data?.segment_ids,\n sender_id: this.data?.sender_id,\n channel_template: this.data?.channel_template,\n create_channels: this.data?.create_channels,\n description: this.data?.description,\n name: this.data?.name,\n user_ids: this.data?.user_ids,\n };\n\n const result = await this.client.createCampaign(body);\n\n this.id = result.campaign.id;\n this.data = result.campaign;\n return result;\n }\n\n verifyCampaignId() {\n if (!this.id) {\n throw new Error(\n 'Campaign id is missing. Either create the campaign using campaign.create() or set the id during instantiation - const campaign = client.campaign(id)',\n );\n }\n }\n\n async start(options?: { scheduledFor?: string; stopAt?: string }) {\n this.verifyCampaignId();\n\n return await this.client.startCampaign(this.id as string, options);\n }\n\n async update(data: Partial<CampaignData>) {\n this.verifyCampaignId();\n\n return this.client.updateCampaign(this.id as string, data);\n }\n\n async delete() {\n this.verifyCampaignId();\n\n return await this.client.deleteCampaign(this.id as string);\n }\n\n async stop() {\n this.verifyCampaignId();\n\n return this.client.stopCampaign(this.id as string);\n }\n\n async get() {\n this.verifyCampaignId();\n\n return this.client.getCampaign(this.id as string);\n }\n}\n","export default function _extends() {\n _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n}","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function _typeof(obj) {\n return typeof obj;\n };\n } else {\n _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}","import objectWithoutPropertiesLoose from \"./objectWithoutPropertiesLoose.js\";\nexport default function _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}","export default function _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val);\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object<any, any>} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[Symbol.iterator];\n\n const iterator = generator.call(obj);\n\n let result;\n\n while ((result = iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array<boolean>}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n value = +value;\n return Number.isFinite(value) ? value : defaultValue;\n}\n\nconst ALPHA = 'abcdefghijklmnopqrstuvwxyz'\n\nconst DIGIT = '0123456789';\n\nconst ALPHABET = {\n DIGIT,\n ALPHA,\n ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT\n}\n\nconst generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {\n let str = '';\n const {length} = alphabet;\n while (size--) {\n str += alphabet[Math.random() * length|0]\n }\n\n return str;\n}\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n ALPHABET,\n generateString,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n response && (this.response = response);\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.response && this.response.status ? this.response.status : null\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n AxiosError.call(axiosError, error.message, code, config, request, response);\n\n axiosError.cause = error;\n\n axiosError.name = error.name;\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array<any>} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object<any, any>} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object<string, any>} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array<String|Number>} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object<string, any>} params - The parameters to be converted to a FormData object.\n * @param {Object<string, any>} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?object} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst isStandardBrowserEnv = (() => {\n let product;\n if (typeof navigator !== 'undefined' && (\n (product = navigator.product) === 'ReactNative' ||\n product === 'NativeScript' ||\n product === 'NS')\n ) {\n return false;\n }\n\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n})();\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\n const isStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n isStandardBrowserEnv,\n isStandardBrowserWebWorkerEnv,\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array<any>} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object<string, any> | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n if (!hasJSONContentType) {\n return data;\n }\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n }\n }, options));\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.isStandardBrowserEnv ?\n\n// Standard browser envs support document.cookie\n (function standardBrowserEnv() {\n return {\n write: function write(name, value, expires, path, domain, secure) {\n const cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n };\n })() :\n\n// Non standard browser env (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return {\n write: function write() {},\n read: function read() { return null; },\n remove: function remove() {}\n };\n })();\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL) {\n if (baseURL && !isAbsoluteURL(requestedURL)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"<scheme>://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.isStandardBrowserEnv ?\n\n// Standard browser envs have full support of the APIs needed to test\n// whether the request URL is of the same origin as current location.\n (function standardBrowserEnv() {\n const msie = /(msie|trident)/i.test(navigator.userAgent);\n const urlParsingNode = document.createElement('a');\n let originURL;\n\n /**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\n function resolveURL(url) {\n let href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n }\n\n originURL = resolveURL(window.location.href);\n\n /**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestURL The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\n return function isURLSameOrigin(requestURL) {\n const parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n return (parsed.protocol === originURL.protocol &&\n parsed.host === originURL.host);\n };\n })() :\n\n // Non standard browser envs (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return function isURLSameOrigin() {\n return true;\n };\n })();\n","'use strict';\n\nimport utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport cookies from './../helpers/cookies.js';\nimport buildURL from './../helpers/buildURL.js';\nimport buildFullPath from '../core/buildFullPath.js';\nimport isURLSameOrigin from './../helpers/isURLSameOrigin.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport speedometer from '../helpers/speedometer.js';\n\nfunction progressEventReducer(listener, isDownloadStream) {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e\n };\n\n data[isDownloadStream ? 'download' : 'upload'] = true;\n\n listener(data);\n };\n}\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n let requestData = config.data;\n const requestHeaders = AxiosHeaders.from(config.headers).normalize();\n const responseType = config.responseType;\n let onCanceled;\n function done() {\n if (config.cancelToken) {\n config.cancelToken.unsubscribe(onCanceled);\n }\n\n if (config.signal) {\n config.signal.removeEventListener('abort', onCanceled);\n }\n }\n\n let contentType;\n\n if (utils.isFormData(requestData)) {\n if (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv) {\n requestHeaders.setContentType(false); // Let the browser set it\n } else if(!requestHeaders.getContentType(/^\\s*multipart\\/form-data/)){\n requestHeaders.setContentType('multipart/form-data'); // mobile/desktop app frameworks\n } else if(utils.isString(contentType = requestHeaders.getContentType())){\n // fix semicolon duplication issue for ReactNative FormData implementation\n requestHeaders.setContentType(contentType.replace(/^\\s*(multipart\\/form-data);+/, '$1'))\n }\n }\n\n let request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n const username = config.auth.username || '';\n const password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n requestHeaders.set('Authorization', 'Basic ' + btoa(username + ':' + password));\n }\n\n const fullPath = buildFullPath(config.baseURL, config.url);\n\n request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = config.transitional || transitionalDefaults;\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (platform.isStandardBrowserEnv) {\n // Add xsrf header\n // regarding CVE-2023-45857 config.withCredentials condition was removed temporarily\n const xsrfValue = isURLSameOrigin(fullPath) && config.xsrfCookieName && cookies.read(config.xsrfCookieName);\n\n if (xsrfValue) {\n requestHeaders.set(config.xsrfHeaderName, xsrfValue);\n }\n }\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(config.withCredentials)) {\n request.withCredentials = !!config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = config.responseType;\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', progressEventReducer(config.onDownloadProgress, true));\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', progressEventReducer(config.onUploadProgress));\n }\n\n if (config.cancelToken || config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n config.cancelToken && config.cancelToken.subscribe(onCanceled);\n if (config.signal) {\n config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(fullPath);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? thing.toJSON() : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)\n };\n\n utils.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","export const VERSION = \"1.6.0\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift.apply(chain, requestInterceptorChain);\n chain.push.apply(chain, responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n i = 0;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","/* eslint-env browser */\nmodule.exports = typeof self == 'object' ? self.FormData : window.FormData;\n","import FormData from 'form-data';\nimport {\n AscDesc,\n ExtendableGenerics,\n DefaultGenerics,\n Logger,\n OwnUserBase,\n OwnUserResponse,\n UserResponse,\n MessageResponse,\n FormatMessageResponse,\n ReactionGroupResponse,\n MessageSet,\n MessagePaginationOptions,\n} from './types';\nimport { AxiosRequestConfig } from 'axios';\n\n/**\n * logChatPromiseExecution - utility function for logging the execution of a promise..\n * use this when you want to run the promise and handle errors by logging a warning\n *\n * @param {Promise<T>} promise The promise you want to run and log\n * @param {string} name A descriptive name of what the promise does for log output\n *\n */\nexport function logChatPromiseExecution<T>(promise: Promise<T>, name: string) {\n promise.then().catch((error) => {\n console.warn(`failed to do ${name}, ran into error: `, error);\n });\n}\n\nexport const sleep = (m: number): Promise<void> => new Promise((r) => setTimeout(r, m));\n\nexport function isFunction<T>(value: Function | T): value is Function {\n return (\n value &&\n (Object.prototype.toString.call(value) === '[object Function]' ||\n 'function' === typeof value ||\n value instanceof Function)\n );\n}\n\nexport const chatCodes = {\n TOKEN_EXPIRED: 40,\n WS_CLOSED_SUCCESS: 1000,\n};\n\nfunction isReadableStream(obj: unknown): obj is NodeJS.ReadStream {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function')\n );\n}\n\nfunction isBuffer(obj: unknown): obj is Buffer {\n return (\n obj != null &&\n (obj as Buffer).constructor != null &&\n // @ts-expect-error\n typeof obj.constructor.isBuffer === 'function' &&\n // @ts-expect-error\n obj.constructor.isBuffer(obj)\n );\n}\n\nfunction isFileWebAPI(uri: unknown): uri is File {\n return typeof window !== 'undefined' && 'File' in window && uri instanceof File;\n}\n\nexport function isOwnUser<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>,\n): user is OwnUserResponse<StreamChatGenerics> {\n return (user as OwnUserResponse<StreamChatGenerics>)?.total_unread_count !== undefined;\n}\n\nfunction isBlobWebAPI(uri: unknown): uri is Blob {\n return typeof window !== 'undefined' && 'Blob' in window && uri instanceof Blob;\n}\n\nexport function isOwnUserBaseProperty(property: string) {\n const ownUserBaseProperties: {\n [Property in keyof Required<OwnUserBase>]: boolean;\n } = {\n channel_mutes: true,\n devices: true,\n mutes: true,\n total_unread_count: true,\n unread_channels: true,\n unread_count: true,\n unread_threads: true,\n invisible: true,\n privacy_settings: true,\n roles: true,\n };\n\n return ownUserBaseProperties[property as keyof OwnUserBase];\n}\n\nexport function addFileToFormData(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n) {\n const data = new FormData();\n\n if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {\n if (name) data.append('file', uri, name);\n else data.append('file', uri);\n } else {\n data.append('file', {\n uri,\n name: name || (uri as string).split('/').reverse()[0],\n contentType: contentType || undefined,\n type: contentType || undefined,\n });\n }\n\n return data;\n}\nexport function normalizeQuerySort<T extends Record<string, AscDesc | undefined>>(sort: T | T[]) {\n const sortFields: Array<{ direction: AscDesc; field: keyof T }> = [];\n const sortArr = Array.isArray(sort) ? sort : [sort];\n for (const item of sortArr) {\n const entries = Object.entries(item) as [keyof T, AscDesc][];\n if (entries.length > 1) {\n console.warn(\n \"client._buildSort() - multiple fields in a single sort object detected. Object's field order is not guaranteed\",\n );\n }\n for (const [field, direction] of entries) {\n sortFields.push({ field, direction });\n }\n }\n return sortFields;\n}\n\n/**\n * retryInterval - A retry interval which increases acc to number of failures\n *\n * @return {number} Duration to wait in milliseconds\n */\nexport function retryInterval(numberOfFailures: number) {\n // try to reconnect in 0.25-25 seconds (random to spread out the load from failures)\n const max = Math.min(500 + numberOfFailures * 2000, 25000);\n const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2000), 25000);\n return Math.floor(Math.random() * (max - min) + min);\n}\n\nexport function randomId() {\n return generateUUIDv4();\n}\n\nfunction hex(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0');\n }\n return s;\n}\n\n// https://tools.ietf.org/html/rfc4122\nexport function generateUUIDv4() {\n const bytes = getRandomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant\n\n return (\n hex(bytes.subarray(0, 4)) +\n '-' +\n hex(bytes.subarray(4, 6)) +\n '-' +\n hex(bytes.subarray(6, 8)) +\n '-' +\n hex(bytes.subarray(8, 10)) +\n '-' +\n hex(bytes.subarray(10, 16))\n );\n}\n\nfunction getRandomValuesWithMathRandom(bytes: Uint8Array): void {\n const max = Math.pow(2, (8 * bytes.byteLength) / bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.random() * max;\n }\n}\ndeclare const msCrypto: Crypto;\n\nconst getRandomValues = (() => {\n if (typeof crypto !== 'undefined' && typeof crypto?.getRandomValues !== 'undefined') {\n return crypto.getRandomValues.bind(crypto);\n } else if (typeof msCrypto !== 'undefined') {\n return msCrypto.getRandomValues.bind(msCrypto);\n } else {\n return getRandomValuesWithMathRandom;\n }\n})();\n\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getRandomValues(bytes);\n return bytes;\n}\n\nexport function convertErrorToJson(err: Error) {\n const jsonObj = {} as Record<string, unknown>;\n\n if (!err) return jsonObj;\n\n try {\n Object.getOwnPropertyNames(err).forEach((key) => {\n jsonObj[key] = Object.getOwnPropertyDescriptor(err, key);\n });\n } catch (_) {\n return {\n error: 'failed to serialize the error',\n };\n }\n\n return jsonObj;\n}\n\n/**\n * isOnline safely return the navigator.online value for browser env\n * if navigator is not in global object, it always return true\n */\nexport function isOnline() {\n const nav =\n typeof navigator !== 'undefined'\n ? navigator\n : typeof window !== 'undefined' && window.navigator\n ? window.navigator\n : undefined;\n\n if (!nav) {\n console.warn('isOnline failed to access window.navigator and assume browser is online');\n return true;\n }\n\n // RN navigator has undefined for onLine\n if (typeof nav.onLine !== 'boolean') {\n return true;\n }\n\n return nav.onLine;\n}\n\n/**\n * listenForConnectionChanges - Adds an event listener fired on browser going online or offline\n */\nexport function addConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('offline', cb);\n window.addEventListener('online', cb);\n }\n}\n\nexport function removeConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.removeEventListener) {\n window.removeEventListener('offline', cb);\n window.removeEventListener('online', cb);\n }\n}\n\nexport const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (params) => {\n const newParams = [];\n for (const k in params) {\n // Stream backend doesn't treat \"undefined\" value same as value not being present.\n // So, we need to skip the undefined values.\n if (params[k] === undefined) continue;\n\n if (Array.isArray(params[k]) || typeof params[k] === 'object') {\n newParams.push(`${k}=${encodeURIComponent(JSON.stringify(params[k]))}`);\n } else {\n newParams.push(`${k}=${encodeURIComponent(params[k])}`);\n }\n }\n\n return newParams.join('&');\n};\n\n/**\n * Takes the message object, parses the dates, sets `__html`\n * and sets the status to `received` if missing; returns a new message object.\n *\n * @param {MessageResponse<StreamChatGenerics>} message `MessageResponse` object\n */\nexport function formatMessage<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: MessageResponse<StreamChatGenerics> | FormatMessageResponse<StreamChatGenerics>,\n): FormatMessageResponse<StreamChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the dates\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),\n deleted_at: message.deleted_at ? new Date(message.deleted_at) : null,\n status: message.status || 'received',\n reaction_groups: maybeGetReactionGroupsFallback(\n message.reaction_groups,\n message.reaction_counts,\n message.reaction_scores,\n ),\n };\n}\n\nexport const findIndexInSortedArray = <T, L>({\n needle,\n sortedArray,\n selectValueToCompare = (e) => e,\n sortDirection = 'ascending',\n}: {\n needle: T;\n sortedArray: readonly T[];\n /**\n * In array of objects (like messages), pick a specific\n * property to compare needle value to.\n *\n * @example\n * ```ts\n * selectValueToCompare: (message) => message.created_at.getTime()\n * ```\n */\n selectValueToCompare?: (arrayElement: T) => L | T;\n /**\n * @default ascending\n * @description\n * ```md\n * ascending - [1,2,3,4,5...]\n * descending - [...5,4,3,2,1]\n * ```\n */\n sortDirection?: 'ascending' | 'descending';\n}) => {\n if (!sortedArray.length) return 0;\n\n let left = 0;\n let right = sortedArray.length - 1;\n let middle = 0;\n\n const recalculateMiddle = () => {\n middle = Math.round((left + right) / 2);\n };\n\n const comparableNeedle = selectValueToCompare(needle);\n\n while (left <= right) {\n recalculateMiddle();\n\n const comparableMiddle = selectValueToCompare(sortedArray[middle]);\n\n // if (comparableNeedle === comparableMiddle) return middle;\n\n if (\n (sortDirection === 'ascending' && comparableNeedle < comparableMiddle) ||\n (sortDirection === 'descending' && comparableNeedle > comparableMiddle)\n ) {\n right = middle - 1;\n } else {\n left = middle + 1;\n }\n }\n\n return left;\n};\n\nexport function addToMessageList<T extends FormatMessageResponse>(\n messages: readonly T[],\n newMessage: T,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n) {\n const addMessageToList = addIfDoesNotExist || timestampChanged;\n let newMessages = [...messages];\n\n // if created_at has changed, message should be filtered and re-inserted in correct order\n // slow op but usually this only happens for a message inserted to state before actual response with correct timestamp\n if (timestampChanged) {\n newMessages = newMessages.filter((message) => !(message.id && newMessage.id === message.id));\n }\n\n // for empty list just concat and return unless it's an update or deletion\n if (newMessages.length === 0 && addMessageToList) {\n return newMessages.concat(newMessage);\n } else if (newMessages.length === 0) {\n return newMessages;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const messageTime = newMessage[sortBy]!.getTime();\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const messageIsNewest = newMessages.at(-1)![sortBy]!.getTime() < messageTime;\n\n // if message is newer than last item in the list concat and return unless it's an update or deletion\n if (messageIsNewest && addMessageToList) {\n return newMessages.concat(newMessage);\n } else if (messageIsNewest) {\n return newMessages;\n }\n\n // find the closest index to push the new message\n const insertionIndex = findIndexInSortedArray({\n needle: newMessage,\n sortedArray: newMessages,\n sortDirection: 'ascending',\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n selectValueToCompare: (m) => m[sortBy]!.getTime(),\n });\n\n // message already exists and not filtered with timestampChanged, update and return\n if (!timestampChanged && newMessage.id) {\n if (newMessages[insertionIndex] && newMessage.id === newMessages[insertionIndex].id) {\n newMessages[insertionIndex] = newMessage;\n return newMessages;\n }\n\n if (newMessages[insertionIndex - 1] && newMessage.id === newMessages[insertionIndex - 1].id) {\n newMessages[insertionIndex - 1] = newMessage;\n return newMessages;\n }\n }\n\n // do not add updated or deleted messages to the list if they already exist or come with a timestamp change\n if (addMessageToList) {\n newMessages.splice(insertionIndex, 0, newMessage);\n }\n\n return newMessages;\n}\n\nfunction maybeGetReactionGroupsFallback(\n groups: { [key: string]: ReactionGroupResponse } | null | undefined,\n counts: { [key: string]: number } | null | undefined,\n scores: { [key: string]: number } | null | undefined,\n): { [key: string]: ReactionGroupResponse } | null {\n if (groups) {\n return groups;\n }\n\n if (counts && scores) {\n const fallback: { [key: string]: ReactionGroupResponse } = {};\n\n for (const type of Object.keys(counts)) {\n fallback[type] = {\n count: counts[type],\n sum_scores: scores[type],\n };\n }\n\n return fallback;\n }\n\n return null;\n}\n\n// works exactly the same as lodash.throttle\nexport const throttle = <T extends (...args: unknown[]) => unknown>(\n fn: T,\n timeout = 200,\n { leading = true, trailing = false }: { leading?: boolean; trailing?: boolean } = {},\n) => {\n let runningTimeout: null | NodeJS.Timeout = null;\n let storedArgs: Parameters<T> | null = null;\n\n return (...args: Parameters<T>) => {\n if (runningTimeout) {\n if (trailing) storedArgs = args;\n return;\n }\n\n if (leading) fn(...args);\n\n const timeoutHandler = () => {\n if (storedArgs) {\n fn(...storedArgs);\n storedArgs = null;\n runningTimeout = setTimeout(timeoutHandler, timeout);\n\n return;\n }\n\n runningTimeout = null;\n };\n\n runningTimeout = setTimeout(timeoutHandler, timeout);\n };\n};\n\ntype MessagePaginationUpdatedParams<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n parentSet: MessageSet;\n requestedPageSize: number;\n returnedPage: MessageResponse<StreamChatGenerics>[];\n logger?: Logger;\n messagePaginationOptions?: MessagePaginationOptions;\n};\n\nexport function binarySearchByDateEqualOrNearestGreater(\n array: {\n created_at?: string;\n }[],\n targetDate: Date,\n): number {\n let left = 0;\n let right = array.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const midCreatedAt = array[mid].created_at;\n if (!midCreatedAt) {\n left += 1;\n continue;\n }\n const midDate = new Date(midCreatedAt);\n\n if (midDate.getTime() === targetDate.getTime()) {\n return mid;\n } else if (midDate.getTime() < targetDate.getTime()) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return left;\n}\n\nconst messagePaginationCreatedAtAround = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n if (!messagePaginationOptions?.created_at_around) return newPagination;\n let hasPrev;\n let hasNext;\n let updateHasPrev;\n let updateHasNext;\n const createdAtAroundDate = new Date(messagePaginationOptions.created_at_around);\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n\n // expect ASC order (from oldest to newest)\n const wholePageHasNewerMessages =\n !!firstPageMsg?.created_at && new Date(firstPageMsg.created_at) > createdAtAroundDate;\n const wholePageHasOlderMessages = !!lastPageMsg?.created_at && new Date(lastPageMsg.created_at) < createdAtAroundDate;\n\n const requestedPageSizeNotMet =\n requestedPageSize > parentSet.messages.length && requestedPageSize > returnedPage.length;\n const noMoreMessages =\n (requestedPageSize > parentSet.messages.length || parentSet.messages.length >= returnedPage.length) &&\n requestedPageSize > returnedPage.length;\n\n if (wholePageHasNewerMessages) {\n hasPrev = false;\n updateHasPrev = true;\n if (requestedPageSizeNotMet) {\n hasNext = false;\n updateHasNext = true;\n }\n } else if (wholePageHasOlderMessages) {\n hasNext = false;\n updateHasNext = true;\n if (requestedPageSizeNotMet) {\n hasPrev = false;\n updateHasPrev = true;\n }\n } else if (noMoreMessages) {\n hasNext = hasPrev = false;\n updateHasPrev = updateHasNext = true;\n } else {\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id && firstPageMsg.id === parentSet.messages[0]?.id,\n lastPageMsg?.id && lastPageMsg.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n updateHasPrev = firstPageMsgIsFirstInSet;\n updateHasNext = lastPageMsgIsLastInSet;\n const midPointByCount = Math.floor(returnedPage.length / 2);\n const midPointByCreationDate = binarySearchByDateEqualOrNearestGreater(returnedPage, createdAtAroundDate);\n\n if (midPointByCreationDate !== -1) {\n hasPrev = midPointByCount <= midPointByCreationDate;\n hasNext = midPointByCount >= midPointByCreationDate;\n }\n }\n\n if (updateHasPrev && typeof hasPrev !== 'undefined') newPagination.hasPrev = hasPrev;\n if (updateHasNext && typeof hasNext !== 'undefined') newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nconst messagePaginationIdAround = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n const { id_around } = messagePaginationOptions || {};\n if (!id_around) return newPagination;\n let hasPrev;\n let hasNext;\n\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id === parentSet.messages[0]?.id,\n lastPageMsg?.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n let updateHasPrev = firstPageMsgIsFirstInSet;\n let updateHasNext = lastPageMsgIsLastInSet;\n\n const midPoint = Math.floor(returnedPage.length / 2);\n const noMoreMessages =\n (requestedPageSize > parentSet.messages.length || parentSet.messages.length >= returnedPage.length) &&\n requestedPageSize > returnedPage.length;\n\n if (noMoreMessages) {\n hasNext = hasPrev = false;\n updateHasPrev = updateHasNext = true;\n } else if (!returnedPage[midPoint]) {\n return newPagination;\n } else if (returnedPage[midPoint].id === id_around) {\n hasPrev = hasNext = true;\n } else {\n let targetMsg;\n const halves = [returnedPage.slice(0, midPoint), returnedPage.slice(midPoint)];\n hasPrev = hasNext = true;\n for (let i = 0; i < halves.length; i++) {\n targetMsg = halves[i].find((message) => message.id === id_around);\n if (targetMsg && i === 0) {\n hasPrev = false;\n }\n if (targetMsg && i === 1) {\n hasNext = false;\n }\n }\n }\n\n if (updateHasPrev && typeof hasPrev !== 'undefined') newPagination.hasPrev = hasPrev;\n if (updateHasNext && typeof hasNext !== 'undefined') newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nconst messagePaginationLinear = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>({\n parentSet,\n requestedPageSize,\n returnedPage,\n messagePaginationOptions,\n}: MessagePaginationUpdatedParams<StreamChatGenerics>) => {\n const newPagination = { ...parentSet.pagination };\n\n let hasPrev;\n let hasNext;\n\n const [firstPageMsg, lastPageMsg] = [returnedPage[0], returnedPage.slice(-1)[0]];\n const [firstPageMsgIsFirstInSet, lastPageMsgIsLastInSet] = [\n firstPageMsg?.id && firstPageMsg.id === parentSet.messages[0]?.id,\n lastPageMsg?.id && lastPageMsg.id === parentSet.messages.slice(-1)[0]?.id,\n ];\n\n const queriedNextMessages =\n messagePaginationOptions &&\n (messagePaginationOptions.created_at_after_or_equal ||\n messagePaginationOptions.created_at_after ||\n messagePaginationOptions.id_gt ||\n messagePaginationOptions.id_gte);\n\n const queriedPrevMessages =\n typeof messagePaginationOptions === 'undefined'\n ? true\n : messagePaginationOptions.created_at_before_or_equal ||\n messagePaginationOptions.created_at_before ||\n messagePaginationOptions.id_lt ||\n messagePaginationOptions.id_lte ||\n messagePaginationOptions.offset;\n\n const containsUnrecognizedOptionsOnly =\n !queriedNextMessages &&\n !queriedPrevMessages &&\n !messagePaginationOptions?.id_around &&\n !messagePaginationOptions?.created_at_around;\n\n const hasMore = returnedPage.length >= requestedPageSize;\n\n if (typeof queriedPrevMessages !== 'undefined' || containsUnrecognizedOptionsOnly) {\n hasPrev = hasMore;\n }\n if (typeof queriedNextMessages !== 'undefined') {\n hasNext = hasMore;\n }\n const returnedPageIsEmpty = returnedPage.length === 0;\n\n if ((firstPageMsgIsFirstInSet || returnedPageIsEmpty) && typeof hasPrev !== 'undefined')\n newPagination.hasPrev = hasPrev;\n if ((lastPageMsgIsLastInSet || returnedPageIsEmpty) && typeof hasNext !== 'undefined')\n newPagination.hasNext = hasNext;\n\n return newPagination;\n};\n\nexport const messageSetPagination = <StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n params: MessagePaginationUpdatedParams<StreamChatGenerics>,\n) => {\n if (params.parentSet.messages.length < params.returnedPage.length) {\n params.logger?.('error', 'Corrupted message set state: parent set size < returned page size');\n return params.parentSet.pagination;\n }\n\n if (params.messagePaginationOptions?.created_at_around) {\n return messagePaginationCreatedAtAround(params);\n } else if (params.messagePaginationOptions?.id_around) {\n return messagePaginationIdAround(params);\n } else {\n return messagePaginationLinear(params);\n }\n};\n","export const DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE = 25;\nexport const DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE = 100;\n\nexport const DEFAULT_MESSAGE_SET_PAGINATION = { hasNext: true, hasPrev: true };\n","import { Channel } from './channel';\nimport {\n ChannelMemberResponse,\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n FormatMessageResponse,\n MessageResponse,\n MessageSet,\n MessageSetType,\n PendingMessageResponse,\n ReactionResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList, formatMessage } from './utils';\nimport { DEFAULT_MESSAGE_SET_PAGINATION } from './constants';\n\ntype ChannelReadStatus<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n {\n last_read: Date;\n unread_messages: number;\n user: UserResponse<StreamChatGenerics>;\n first_unread_message_id?: string;\n last_read_message_id?: string;\n }\n>;\n\n/**\n * ChannelState - A container class for the channel state.\n */\nexport class ChannelState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _channel: Channel<StreamChatGenerics>;\n watcher_count: number;\n typing: Record<string, Event<StreamChatGenerics>>;\n read: ChannelReadStatus<StreamChatGenerics>;\n pinnedMessages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>;\n pending_messages: Array<PendingMessageResponse<StreamChatGenerics>>;\n threads: Record<string, Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>>;\n mutedUsers: Array<UserResponse<StreamChatGenerics>>;\n watchers: Record<string, UserResponse<StreamChatGenerics>>;\n members: Record<string, ChannelMemberResponse<StreamChatGenerics>>;\n unreadCount: number;\n membership: ChannelMemberResponse<StreamChatGenerics>;\n last_message_at: Date | null;\n /**\n * Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n isUpToDate: boolean;\n /**\n * Disjoint lists of messages\n * Users can jump in the message list (with searching) and this can result in disjoint lists of messages\n * The state manages these lists and merges them when lists overlap\n * The messages array contains the currently active set\n */\n messageSets: MessageSet[] = [];\n\n constructor(channel: Channel<StreamChatGenerics>) {\n this._channel = channel;\n this.watcher_count = 0;\n this.typing = {};\n this.read = {};\n this.initMessages();\n this.pinnedMessages = [];\n this.pending_messages = [];\n this.threads = {};\n // a list of users to hide messages from\n this.mutedUsers = [];\n this.watchers = {};\n this.members = {};\n this.membership = {};\n this.unreadCount = 0;\n /**\n * Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n this.isUpToDate = true;\n this.last_message_at = channel?.state?.last_message_at != null ? new Date(channel.state.last_message_at) : null;\n }\n\n get messages() {\n return this.messageSets.find((s) => s.isCurrent)?.messages || [];\n }\n\n set messages(messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isCurrent);\n this.messageSets[index].messages = messages;\n }\n\n /**\n * The list of latest messages\n * The messages array not always contains the latest messages (for example if a user searched for an earlier message, that is in a different message set)\n */\n get latestMessages() {\n return this.messageSets.find((s) => s.isLatest)?.messages || [];\n }\n\n set latestMessages(messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isLatest);\n this.messageSets[index].messages = messages;\n }\n\n get messagePagination() {\n return this.messageSets.find((s) => s.isCurrent)?.pagination || DEFAULT_MESSAGE_SET_PAGINATION;\n }\n\n /**\n * addMessageSorted - Add a message to the state\n *\n * @param {MessageResponse<StreamChatGenerics>} newMessage A new message\n * @param {boolean} timestampChanged Whether updating a message with changed created_at value.\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if message is not in the list (only used if addIfDoesNotExist is true)\n */\n addMessageSorted(\n newMessage: MessageResponse<StreamChatGenerics>,\n timestampChanged = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n return this.addMessagesSorted(\n [newMessage],\n timestampChanged,\n false,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n }\n\n /**\n * Takes the message object, parses the dates, sets `__html`\n * and sets the status to `received` if missing; returns a new message object.\n *\n * @param {MessageResponse<StreamChatGenerics>} message `MessageResponse` object\n */\n formatMessage = (message: MessageResponse<StreamChatGenerics>) => formatMessage<StreamChatGenerics>(message);\n\n /**\n * addMessagesSorted - Add the list of messages to state and resorts the messages\n *\n * @param {Array<MessageResponse<StreamChatGenerics>>} newMessages A list of messages\n * @param {boolean} timestampChanged Whether updating messages with changed created_at value.\n * @param {boolean} initializing Whether channel is being initialized.\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist Which message set to add to if messages are not in the list (only used if addIfDoesNotExist is true)\n *\n */\n addMessagesSorted(\n newMessages: MessageResponse<StreamChatGenerics>[],\n timestampChanged = false,\n initializing = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n const { messagesToAdd, targetMessageSetIndex } = this.findTargetMessageSet(\n newMessages,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n\n for (let i = 0; i < messagesToAdd.length; i += 1) {\n const isFromShadowBannedUser = messagesToAdd[i].shadowed;\n if (isFromShadowBannedUser) {\n continue;\n }\n // If message is already formatted we can skip the tasks below\n // This will be true for messages that are already present at the state -> this happens when we perform merging of message sets\n // This will be also true for message previews used by some SDKs\n const isMessageFormatted = messagesToAdd[i].created_at instanceof Date;\n let message: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n if (isMessageFormatted) {\n message = messagesToAdd[i] as ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n } else {\n message = this.formatMessage(messagesToAdd[i] as MessageResponse<StreamChatGenerics>);\n\n if (message.user && this._channel?.cid) {\n /**\n * Store the reference to user for this channel, so that when we have to\n * handle updates to user, we can use the reference map, to determine which\n * channels need to be updated with updated user object.\n */\n this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);\n }\n\n if (initializing && message.id && this.threads[message.id]) {\n // If we are initializing the state of channel (e.g., in case of connection recovery),\n // then in that case we remove thread related to this message from threads object.\n // This way we can ensure that we don't have any stale data in thread object\n // and consumer can refetch the replies.\n delete this.threads[message.id];\n }\n\n if (!this.last_message_at) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n\n if (message.created_at.getTime() > this.last_message_at.getTime()) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n }\n\n // update or append the messages...\n const parentID = message.parent_id;\n\n // add to the given message set\n if ((!parentID || message.show_in_channel) && targetMessageSetIndex !== -1) {\n this.messageSets[targetMessageSetIndex].messages = this._addToMessageList(\n this.messageSets[targetMessageSetIndex].messages,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n\n /**\n * Add message to thread if applicable and the message\n * was added when querying for replies, or the thread already exits.\n * This is to prevent the thread state from getting out of sync if\n * a thread message is shown in channel but older than the newest thread\n * message. This situation can result in a thread state where a random\n * message is \"oldest\" message, and newer messages are therefore not loaded.\n * This can also occur if an old thread message is updated.\n */\n if (parentID && !initializing) {\n const thread = this.threads[parentID] || [];\n this.threads[parentID] = this._addToMessageList(\n thread,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n }\n\n return {\n messageSet: this.messageSets[targetMessageSetIndex],\n };\n }\n\n /**\n * addPinnedMessages - adds messages in pinnedMessages property\n *\n * @param {Array<MessageResponse<StreamChatGenerics>>} pinnedMessages A list of pinned messages\n *\n */\n addPinnedMessages(pinnedMessages: MessageResponse<StreamChatGenerics>[]) {\n for (let i = 0; i < pinnedMessages.length; i += 1) {\n this.addPinnedMessage(pinnedMessages[i]);\n }\n }\n\n /**\n * addPinnedMessage - adds message in pinnedMessages\n *\n * @param {MessageResponse<StreamChatGenerics>} pinnedMessage message to update\n *\n */\n addPinnedMessage(pinnedMessage: MessageResponse<StreamChatGenerics>) {\n this.pinnedMessages = this._addToMessageList(\n this.pinnedMessages,\n this.formatMessage(pinnedMessage),\n false,\n 'pinned_at',\n );\n }\n\n /**\n * removePinnedMessage - removes pinned message from pinnedMessages\n *\n * @param {MessageResponse<StreamChatGenerics>} message message to remove\n *\n */\n removePinnedMessage(message: MessageResponse<StreamChatGenerics>) {\n const { result } = this.removeMessageFromArray(this.pinnedMessages, message);\n this.pinnedMessages = result;\n }\n\n addReaction(\n reaction: ReactionResponse<StreamChatGenerics>,\n message?: MessageResponse<StreamChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._addOwnReactionToMessage(msg.own_reactions, reaction, enforce_unique);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _addOwnReactionToMessage(\n ownReactions: ReactionResponse<StreamChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<StreamChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (enforce_unique) {\n ownReactions = [];\n } else {\n ownReactions = this._removeOwnReactionFromMessage(ownReactions, reaction);\n }\n\n ownReactions = ownReactions || [];\n if (this._channel.getClient().userID === reaction.user_id) {\n ownReactions.push(reaction);\n }\n\n return ownReactions;\n }\n\n _removeOwnReactionFromMessage(\n ownReactions: ReactionResponse<StreamChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<StreamChatGenerics>,\n ) {\n if (ownReactions) {\n return ownReactions.filter((item) => item.user_id !== reaction.user_id || item.type !== reaction.type);\n }\n return ownReactions;\n }\n\n removeReaction(reaction: ReactionResponse<StreamChatGenerics>, message?: MessageResponse<StreamChatGenerics>) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._removeOwnReactionFromMessage(msg.own_reactions, reaction);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _updateQuotedMessageReferences({\n message,\n remove,\n }: {\n message: MessageResponse<StreamChatGenerics>;\n remove?: boolean;\n }) {\n const parseMessage = (m: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>) =>\n (({\n ...m,\n created_at: m.created_at.toISOString(),\n pinned_at: m.pinned_at?.toISOString(),\n updated_at: m.updated_at?.toISOString(),\n } as unknown) as MessageResponse<StreamChatGenerics>);\n\n const update = (messages: FormatMessageResponse<StreamChatGenerics>[]) => {\n const updatedMessages = messages.reduce<MessageResponse<StreamChatGenerics>[]>((acc, msg) => {\n if (msg.quoted_message_id === message.id) {\n acc.push({ ...parseMessage(msg), quoted_message: remove ? { ...message, attachments: [] } : message });\n }\n return acc;\n }, []);\n this.addMessagesSorted(updatedMessages, true);\n };\n\n if (!message.parent_id) {\n this.messageSets.forEach((set) => update(set.messages));\n } else if (message.parent_id && this.threads[message.parent_id]) {\n // prevent going through all the threads even though it is possible to quote a message from another thread\n update(this.threads[message.parent_id]);\n }\n }\n\n removeQuotedMessageReferences(message: MessageResponse<StreamChatGenerics>) {\n this._updateQuotedMessageReferences({ message, remove: true });\n }\n\n /**\n * Updates all instances of given message in channel state\n * @param message\n * @param updateFunc\n */\n _updateMessage(\n message: {\n id?: string;\n parent_id?: string;\n pinned?: boolean;\n show_in_channel?: boolean;\n },\n updateFunc: (\n msg: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n ) => ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n ) {\n const { parent_id, show_in_channel, pinned } = message;\n\n if (parent_id && this.threads[parent_id]) {\n const thread = this.threads[parent_id];\n const msgIndex = thread.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n thread[msgIndex] = updateFunc(thread[msgIndex]);\n this.threads[parent_id] = thread;\n }\n }\n\n if ((!show_in_channel && !parent_id) || show_in_channel) {\n const messageSetIndex = this.findMessageSetIndex(message);\n if (messageSetIndex !== -1) {\n const msgIndex = this.messageSets[messageSetIndex].messages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.messageSets[messageSetIndex].messages[msgIndex] = updateFunc(\n this.messageSets[messageSetIndex].messages[msgIndex],\n );\n }\n }\n }\n\n if (pinned) {\n const msgIndex = this.pinnedMessages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.pinnedMessages[msgIndex] = updateFunc(this.pinnedMessages[msgIndex]);\n }\n }\n }\n\n /**\n * Setter for isUpToDate.\n *\n * @param isUpToDate Flag which indicates if channel state contain latest/recent messages or no.\n * This flag should be managed by UI sdks using a setter - setIsUpToDate.\n * When false, any new message (received by websocket event - message.new) will not\n * be pushed on to message list.\n */\n setIsUpToDate = (isUpToDate: boolean) => {\n this.isUpToDate = isUpToDate;\n };\n\n /**\n * _addToMessageList - Adds a message to a list of messages, tries to update first, appends if message isn't found\n *\n * @param {Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>} messages A list of messages\n * @param message\n * @param {boolean} timestampChanged Whether updating a message with changed created_at value.\n * @param {string} sortBy field name to use to sort the messages by\n * @param {boolean} addIfDoesNotExist Add message if it is not in the list, used to prevent out of order updated messages from being added.\n */\n _addToMessageList(\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n message: ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n ) {\n return addToMessageList(messages, message, timestampChanged, sortBy, addIfDoesNotExist);\n }\n\n /**\n * removeMessage - Description\n *\n * @param {{ id: string; parent_id?: string }} messageToRemove Object of the message to remove. Needs to have at id specified.\n *\n * @return {boolean} Returns if the message was removed\n */\n removeMessage(messageToRemove: { id: string; messageSetIndex?: number; parent_id?: string }) {\n let isRemoved = false;\n if (messageToRemove.parent_id && this.threads[messageToRemove.parent_id]) {\n const { removed, result: threadMessages } = this.removeMessageFromArray(\n this.threads[messageToRemove.parent_id],\n messageToRemove,\n );\n\n this.threads[messageToRemove.parent_id] = threadMessages;\n isRemoved = removed;\n } else {\n const messageSetIndex = messageToRemove.messageSetIndex ?? this.findMessageSetIndex(messageToRemove);\n if (messageSetIndex !== -1) {\n const { removed, result: messages } = this.removeMessageFromArray(\n this.messageSets[messageSetIndex].messages,\n messageToRemove,\n );\n this.messageSets[messageSetIndex].messages = messages;\n isRemoved = removed;\n }\n }\n\n return isRemoved;\n }\n\n removeMessageFromArray = (\n msgArray: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n msg: { id: string; parent_id?: string },\n ) => {\n const result = msgArray.filter((message) => !(!!message.id && !!msg.id && message.id === msg.id));\n\n return { removed: result.length < msgArray.length, result };\n };\n\n /**\n * Updates the message.user property with updated user object, for messages.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n updateUserMessages = (user: UserResponse<StreamChatGenerics>) => {\n const _updateUserMessages = (\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n user: UserResponse<StreamChatGenerics>,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id === user.id) {\n messages[i] = { ...m, user };\n }\n }\n };\n\n this.messageSets.forEach((set) => _updateUserMessages(set.messages, user));\n\n for (const parentId in this.threads) {\n _updateUserMessages(this.threads[parentId], user);\n }\n\n _updateUserMessages(this.pinnedMessages, user);\n };\n\n /**\n * Marks the messages as deleted, from deleted user.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n * @param {boolean} hardDelete\n */\n deleteUserMessages = (user: UserResponse<StreamChatGenerics>, hardDelete = false) => {\n const _deleteUserMessages = (\n messages: Array<ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>>,\n user: UserResponse<StreamChatGenerics>,\n hardDelete = false,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id !== user.id) {\n continue;\n }\n\n if (hardDelete) {\n /**\n * In case of hard delete, we need to strip down all text, html,\n * attachments and all the custom properties on message\n */\n messages[i] = ({\n cid: m.cid,\n created_at: m.created_at,\n deleted_at: user.deleted_at,\n id: m.id,\n latest_reactions: [],\n mentioned_users: [],\n own_reactions: [],\n parent_id: m.parent_id,\n reply_count: m.reply_count,\n status: m.status,\n thread_participants: m.thread_participants,\n type: 'deleted',\n updated_at: m.updated_at,\n user: m.user,\n } as unknown) as ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>;\n } else {\n messages[i] = {\n ...m,\n type: 'deleted',\n deleted_at: user.deleted_at ? new Date(user.deleted_at) : null,\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _deleteUserMessages(set.messages, user, hardDelete));\n\n for (const parentId in this.threads) {\n _deleteUserMessages(this.threads[parentId], user, hardDelete);\n }\n\n _deleteUserMessages(this.pinnedMessages, user, hardDelete);\n };\n\n /**\n * filterErrorMessages - Removes error messages from the channel state.\n *\n */\n filterErrorMessages() {\n const filteredMessages = this.latestMessages.filter((message) => message.type !== 'error');\n\n this.latestMessages = filteredMessages;\n }\n\n /**\n * clean - Remove stale data such as users that stayed in typing state for more than 5 seconds\n */\n clean() {\n const now = new Date();\n // prevent old users from showing up as typing\n for (const [userID, lastEvent] of Object.entries(this.typing)) {\n const receivedAt =\n typeof lastEvent.received_at === 'string'\n ? new Date(lastEvent.received_at)\n : lastEvent.received_at || new Date();\n if (now.getTime() - receivedAt.getTime() > 7000) {\n delete this.typing[userID];\n this._channel.getClient().dispatchEvent({\n cid: this._channel.cid,\n type: 'typing.stop',\n user: { id: userID },\n } as Event<StreamChatGenerics>);\n }\n }\n }\n\n clearMessages() {\n this.initMessages();\n this.pinnedMessages = [];\n }\n\n initMessages() {\n this.messageSets = [{ messages: [], isLatest: true, isCurrent: true, pagination: DEFAULT_MESSAGE_SET_PAGINATION }];\n }\n\n /**\n * loadMessageIntoState - Loads a given message (and messages around it) into the state\n *\n * @param {string} messageId The id of the message, or 'latest' to indicate switching to the latest messages\n * @param {string} parentMessageId The id of the parent message, if we want load a thread reply\n * @param {number} limit The page size if the message has to be queried from the server\n */\n async loadMessageIntoState(messageId: string | 'latest', parentMessageId?: string, limit = 25) {\n let messageSetIndex: number;\n let switchedToMessageSet = false;\n let loadedMessageThread = false;\n const messageIdToFind = parentMessageId || messageId;\n if (messageId === 'latest') {\n if (this.messages === this.latestMessages) {\n return;\n }\n messageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n } else {\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n }\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n switchedToMessageSet = true;\n }\n loadedMessageThread = !parentMessageId || !!this.threads[parentMessageId]?.find((m) => m.id === messageId);\n if (switchedToMessageSet && loadedMessageThread) {\n return;\n }\n if (!switchedToMessageSet) {\n await this._channel.query({ messages: { id_around: messageIdToFind, limit } }, 'new');\n }\n if (!loadedMessageThread && parentMessageId) {\n await this._channel.getReplies(parentMessageId, { id_around: messageId, limit });\n }\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n }\n }\n\n /**\n * findMessage - Finds a message inside the state\n *\n * @param {string} messageId The id of the message\n * @param {string} parentMessageId The id of the parent message, if we want load a thread reply\n *\n * @return {ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>} Returns the message, or undefined if the message wasn't found\n */\n findMessage(messageId: string, parentMessageId?: string) {\n if (parentMessageId) {\n const messages = this.threads[parentMessageId];\n if (!messages) {\n return undefined;\n }\n return messages.find((m) => m.id === messageId);\n }\n\n const messageSetIndex = this.findMessageSetIndex({ id: messageId });\n if (messageSetIndex === -1) {\n return undefined;\n }\n return this.messageSets[messageSetIndex].messages.find((m) => m.id === messageId);\n }\n\n private switchToMessageSet(index: number) {\n const currentMessages = this.messageSets.find((s) => s.isCurrent);\n if (!currentMessages) {\n return;\n }\n currentMessages.isCurrent = false;\n this.messageSets[index].isCurrent = true;\n }\n\n private areMessageSetsOverlap(messages1: Array<{ id: string }>, messages2: Array<{ id: string }>) {\n return messages1.some((m1) => messages2.find((m2) => m1.id === m2.id));\n }\n\n private findMessageSetIndex(message: { id?: string }) {\n return this.messageSets.findIndex((set) => !!set.messages.find((m) => m.id === message.id));\n }\n\n private findTargetMessageSet(\n newMessages: MessageResponse<StreamChatGenerics>[],\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n let messagesToAdd: (\n | MessageResponse<StreamChatGenerics>\n | ReturnType<ChannelState<StreamChatGenerics>['formatMessage']>\n )[] = newMessages;\n let targetMessageSetIndex!: number;\n if (addIfDoesNotExist) {\n const overlappingMessageSetIndices = this.messageSets\n .map((_, i) => i)\n .filter((i) => this.areMessageSetsOverlap(this.messageSets[i].messages, newMessages));\n switch (messageSetToAddToIfDoesNotExist) {\n case 'new':\n if (overlappingMessageSetIndices.length > 0) {\n targetMessageSetIndex = overlappingMessageSetIndices[0];\n // No new message set is created if newMessages only contains thread replies\n } else if (newMessages.some((m) => !m.parent_id)) {\n this.messageSets.push({\n messages: [],\n isCurrent: false,\n isLatest: false,\n pagination: DEFAULT_MESSAGE_SET_PAGINATION,\n });\n targetMessageSetIndex = this.messageSets.length - 1;\n }\n break;\n case 'current':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isCurrent);\n break;\n case 'latest':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n break;\n default:\n targetMessageSetIndex = -1;\n }\n // when merging the target set will be the first one from the overlapping message sets\n const mergeTargetMessageSetIndex = overlappingMessageSetIndices.splice(0, 1)[0];\n const mergeSourceMessageSetIndices = [...overlappingMessageSetIndices];\n if (mergeTargetMessageSetIndex !== undefined && mergeTargetMessageSetIndex !== targetMessageSetIndex) {\n mergeSourceMessageSetIndices.push(targetMessageSetIndex);\n }\n // merge message sets\n if (mergeSourceMessageSetIndices.length > 0) {\n const target = this.messageSets[mergeTargetMessageSetIndex];\n const sources = this.messageSets.filter((_, i) => mergeSourceMessageSetIndices.indexOf(i) !== -1);\n sources.forEach((messageSet) => {\n target.isLatest = target.isLatest || messageSet.isLatest;\n target.isCurrent = target.isCurrent || messageSet.isCurrent;\n target.pagination.hasPrev =\n messageSet.messages[0].created_at < target.messages[0].created_at\n ? messageSet.pagination.hasPrev\n : target.pagination.hasPrev;\n target.pagination.hasNext =\n target.messages.slice(-1)[0].created_at < messageSet.messages.slice(-1)[0].created_at\n ? messageSet.pagination.hasNext\n : target.pagination.hasNext;\n messagesToAdd = [...messagesToAdd, ...messageSet.messages];\n });\n sources.forEach((s) => this.messageSets.splice(this.messageSets.indexOf(s), 1));\n const overlappingMessageSetIndex = this.messageSets.findIndex((s) =>\n this.areMessageSetsOverlap(s.messages, newMessages),\n );\n targetMessageSetIndex = overlappingMessageSetIndex;\n }\n } else {\n // assumes that all new messages belong to the same set\n targetMessageSetIndex = this.findMessageSetIndex(newMessages[0]);\n }\n\n return { targetMessageSetIndex, messagesToAdd };\n }\n}\n","import { ChannelState } from './channel_state';\nimport { logChatPromiseExecution, messageSetPagination, normalizeQuerySort } from './utils';\nimport { StreamChat } from './client';\nimport {\n APIResponse,\n BanUserOptions,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelMemberAPIResponse,\n ChannelMemberResponse,\n ChannelQueryOptions,\n ChannelResponse,\n ChannelUpdateOptions,\n CreateCallOptions,\n CreateCallResponse,\n DefaultGenerics,\n DeleteChannelAPIResponse,\n Event,\n EventAPIResponse,\n EventHandler,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n GetMultipleMessagesAPIResponse,\n GetReactionsAPIResponse,\n GetRepliesAPIResponse,\n InviteOptions,\n MarkReadOptions,\n MarkUnreadOptions,\n MemberFilters,\n MemberSort,\n Message,\n MessageFilters,\n MessagePaginationOptions,\n MessageResponse,\n MessageSetType,\n MuteChannelAPIResponse,\n NewMemberPayload,\n PartialUpdateChannel,\n PartialUpdateChannelAPIResponse,\n PartialUpdateMember,\n PinnedMessagePaginationOptions,\n PinnedMessagesSort,\n QueryMembersOptions,\n Reaction,\n ReactionAPIResponse,\n SearchAPIResponse,\n SearchMessageSortBase,\n SearchOptions,\n SearchPayload,\n SendMessageAPIResponse,\n TruncateChannelAPIResponse,\n TruncateOptions,\n UpdateChannelAPIResponse,\n UserResponse,\n QueryChannelAPIResponse,\n PollVoteData,\n SendMessageOptions,\n AscDesc,\n PartialUpdateMemberAPIResponse,\n} from './types';\nimport { Role } from './permissions';\nimport { DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE } from './constants';\n\n/**\n * Channel - The Channel class manages it's own state.\n */\nexport class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _client: StreamChat<StreamChatGenerics>;\n type: string;\n id: string | undefined;\n data: ChannelData<StreamChatGenerics> | ChannelResponse<StreamChatGenerics> | undefined;\n _data: ChannelData<StreamChatGenerics> | ChannelResponse<StreamChatGenerics>;\n cid: string;\n /** */\n listeners: { [key: string]: (string | EventHandler<StreamChatGenerics>)[] };\n state: ChannelState<StreamChatGenerics>;\n /**\n * This boolean is a vague indication of weather the channel exists on chat backend.\n *\n * If the value is true, then that means the channel has been initialized by either calling\n * channel.create() or channel.query() or channel.watch().\n *\n * If the value is false, then channel may or may not exist on the backend. The only way to ensure\n * is by calling channel.create() or channel.query() or channel.watch().\n */\n initialized: boolean;\n /**\n * Indicates weather channel has been initialized by manually populating the state with some messages, members etc.\n * Static state indicates that channel exists on backend, but is not being watched yet.\n */\n offlineMode: boolean;\n lastKeyStroke?: Date;\n lastTypingEvent: Date | null;\n isTyping: boolean;\n disconnected: boolean;\n\n /**\n * constructor - Create a channel\n *\n * @param {StreamChat<StreamChatGenerics>} client the chat client\n * @param {string} type the type of channel\n * @param {string} [id] the id of the chat\n * @param {ChannelData<StreamChatGenerics>} data any additional custom params\n *\n * @return {Channel<StreamChatGenerics>} Returns a new uninitialized channel\n */\n constructor(\n client: StreamChat<StreamChatGenerics>,\n type: string,\n id: string | undefined,\n data: ChannelData<StreamChatGenerics>,\n ) {\n const validTypeRe = /^[\\w_-]+$/;\n const validIDRe = /^[\\w!_-]+$/;\n\n if (!validTypeRe.test(type)) {\n throw new Error(`Invalid chat type ${type}, letters, numbers and \"_-\" are allowed`);\n }\n if (typeof id === 'string' && !validIDRe.test(id)) {\n throw new Error(`Invalid chat id ${id}, letters, numbers and \"!-_\" are allowed`);\n }\n\n this._client = client;\n this.type = type;\n this.id = id;\n // used by the frontend, gets updated:\n this.data = data;\n // this._data is used for the requests...\n this._data = { ...data };\n this.cid = `${type}:${id}`;\n this.listeners = {};\n // perhaps the state variable should be private\n this.state = new ChannelState<StreamChatGenerics>(this);\n this.initialized = false;\n this.offlineMode = false;\n this.lastTypingEvent = null;\n this.isTyping = false;\n this.disconnected = false;\n }\n\n /**\n * getClient - Get the chat client for this channel. If client.disconnect() was called, this function will error\n *\n * @return {StreamChat<StreamChatGenerics>}\n */\n getClient(): StreamChat<StreamChatGenerics> {\n if (this.disconnected === true) {\n throw Error(`You can't use a channel after client.disconnect() was called`);\n }\n return this._client;\n }\n\n /**\n * getConfig - Get the config for this channel id (cid)\n *\n * @return {Record<string, unknown>}\n */\n getConfig() {\n const client = this.getClient();\n return client.configs[this.cid];\n }\n\n /**\n * sendMessage - Send a message to this channel\n *\n * @param {Message<StreamChatGenerics>} message The Message object\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n * @param {boolean} [options.skip_push] Skip sending push notifications\n * @param {boolean} [options.is_pending_message] DEPRECATED, please use `pending` instead.\n * @param {boolean} [options.pending] Make this message pending\n * @param {Record<string,string>} [options.pending_message_metadata] Metadata for the pending message\n * @param {boolean} [options.force_moderation] Apply force moderation for server-side requests\n *\n * @return {Promise<SendMessageAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendMessage(message: Message<StreamChatGenerics>, options?: SendMessageOptions) {\n return await this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(this._channelURL() + '/message', {\n message,\n ...options,\n });\n }\n\n sendFile(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/file`, uri, name, contentType, user);\n }\n\n sendImage(\n uri: string | NodeJS.ReadableStream | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/image`, uri, name, contentType, user);\n }\n\n deleteFile(url: string) {\n return this.getClient().delete<APIResponse>(`${this._channelURL()}/file`, { url });\n }\n\n deleteImage(url: string) {\n return this.getClient().delete<APIResponse>(`${this._channelURL()}/image`, { url });\n }\n\n /**\n * sendEvent - Send an event on this channel\n *\n * @param {Event<StreamChatGenerics>} event for example {type: 'message.read'}\n *\n * @return {Promise<EventAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendEvent(event: Event<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().post<EventAPIResponse<StreamChatGenerics>>(this._channelURL() + '/event', {\n event,\n });\n }\n\n /**\n * search - Query messages\n *\n * @param {MessageFilters<StreamChatGenerics> | string} query search query or object MongoDB style filters\n * @param {{client_id?: string; connection_id?: string; query?: string; message_filter_conditions?: MessageFilters<StreamChatGenerics>}} options Option object, {user_id: 'tommaso'}\n *\n * @return {Promise<SearchAPIResponse<StreamChatGenerics>>} search messages response\n */\n async search(\n query: MessageFilters<StreamChatGenerics> | string,\n options: SearchOptions<StreamChatGenerics> & {\n client_id?: string;\n connection_id?: string;\n message_filter_conditions?: MessageFilters<StreamChatGenerics>;\n query?: string;\n } = {},\n ) {\n if (options.offset && options.next) {\n throw Error(`Cannot specify offset with next`);\n }\n // Return a list of channels\n const payload: SearchPayload<StreamChatGenerics> = {\n filter_conditions: { cid: this.cid } as ChannelFilters<StreamChatGenerics>,\n ...options,\n sort: options.sort ? normalizeQuerySort<SearchMessageSortBase<StreamChatGenerics>>(options.sort) : undefined,\n };\n if (typeof query === 'string') {\n payload.query = query;\n } else if (typeof query === 'object') {\n payload.message_filter_conditions = query;\n } else {\n throw Error(`Invalid type ${typeof query} for query parameter`);\n }\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n return await this.getClient().get<SearchAPIResponse<StreamChatGenerics>>(this.getClient().baseURL + '/search', {\n payload,\n });\n }\n\n /**\n * queryMembers - Query Members\n *\n * @param {MemberFilters<StreamChatGenerics>} filterConditions object MongoDB style filters\n * @param {MemberSort<StreamChatGenerics>} [sort] Sort options, for instance [{created_at: -1}].\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{name: -1}, {created_at: 1}]\n * @param {{ limit?: number; offset?: number }} [options] Option object, {limit: 10, offset:10}\n *\n * @return {Promise<ChannelMemberAPIResponse<StreamChatGenerics>>} Query Members response\n */\n async queryMembers(\n filterConditions: MemberFilters<StreamChatGenerics>,\n sort: MemberSort<StreamChatGenerics> = [],\n options: QueryMembersOptions = {},\n ) {\n let id: string | undefined;\n const type = this.type;\n let members: string[] | ChannelMemberResponse<StreamChatGenerics>[] | undefined;\n if (this.id) {\n id = this.id;\n } else if (this.data?.members && Array.isArray(this.data.members)) {\n members = this.data.members;\n }\n // Return a list of members\n return await this.getClient().get<ChannelMemberAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + '/members',\n {\n payload: {\n type,\n id,\n members,\n sort: normalizeQuerySort(sort),\n filter_conditions: filterConditions,\n ...options,\n },\n },\n );\n }\n\n /**\n * partialUpdateMember - Partial update a member\n *\n * @param {string} user_id member user id\n * @param {PartialUpdateMember<StreamChatGenerics>} updates\n *\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} Updated member\n */\n async partialUpdateMember(user_id: string, updates: PartialUpdateMember<StreamChatGenerics>) {\n if (!user_id) {\n throw Error('Please specify the user id');\n }\n\n return await this.getClient().patch<PartialUpdateMemberAPIResponse<StreamChatGenerics>>(\n this._channelURL() + `/member/${encodeURIComponent(user_id)}`,\n updates,\n );\n }\n\n /**\n * sendReaction - Send a reaction about a message\n *\n * @param {string} messageID the message id\n * @param {Reaction<StreamChatGenerics>} reaction the reaction object for instance {type: 'love'}\n * @param {{ enforce_unique?: boolean, skip_push?: boolean }} [options] Option object, {enforce_unique: true, skip_push: true} to override any existing reaction or skip sending push notifications\n *\n * @return {Promise<ReactionAPIResponse<StreamChatGenerics>>} The Server Response\n */\n async sendReaction(\n messageID: string,\n reaction: Reaction<StreamChatGenerics>,\n options?: { enforce_unique?: boolean; skip_push?: boolean },\n ) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n if (!reaction || Object.keys(reaction).length === 0) {\n throw Error(`Reaction object is missing`);\n }\n return await this.getClient().post<ReactionAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/reaction`,\n {\n reaction,\n ...options,\n },\n );\n }\n\n /**\n * deleteReaction - Delete a reaction by user and type\n *\n * @param {string} messageID the id of the message from which te remove the reaction\n * @param {string} reactionType the type of reaction that should be removed\n * @param {string} [user_id] the id of the user (used only for server side request) default null\n *\n * @return {Promise<ReactionAPIResponse<StreamChatGenerics>>} The Server Response\n */\n deleteReaction(messageID: string, reactionType: string, user_id?: string) {\n this._checkInitialized();\n if (!reactionType || !messageID) {\n throw Error('Deleting a reaction requires specifying both the message and reaction type');\n }\n\n const url =\n this.getClient().baseURL +\n `/messages/${encodeURIComponent(messageID)}/reaction/${encodeURIComponent(reactionType)}`;\n //provided when server side request\n if (user_id) {\n return this.getClient().delete<ReactionAPIResponse<StreamChatGenerics>>(url, { user_id });\n }\n\n return this.getClient().delete<ReactionAPIResponse<StreamChatGenerics>>(url, {});\n }\n\n /**\n * update - Edit the channel's custom properties\n *\n * @param {ChannelData<StreamChatGenerics>} channelData The object to update the custom properties of this channel with\n * @param {Message<StreamChatGenerics>} [updateMessage] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async update(\n channelData: Partial<ChannelData<StreamChatGenerics>> | Partial<ChannelResponse<StreamChatGenerics>> = {},\n updateMessage?: Message<StreamChatGenerics>,\n options?: ChannelUpdateOptions,\n ) {\n // Strip out reserved names that will result in API errors.\n const reserved = [\n 'config',\n 'cid',\n 'created_by',\n 'id',\n 'member_count',\n 'type',\n 'created_at',\n 'updated_at',\n 'last_message_at',\n 'own_capabilities',\n ];\n reserved.forEach((key) => {\n delete channelData[key];\n });\n\n return await this._update({\n message: updateMessage,\n data: channelData,\n ...options,\n });\n }\n\n /**\n * updatePartial - partial update channel properties\n *\n * @param {PartialUpdateChannel<StreamChatGenerics>} partial update request\n *\n * @return {Promise<PartialUpdateChannelAPIResponse<StreamChatGenerics>>}\n */\n async updatePartial(update: PartialUpdateChannel<StreamChatGenerics>) {\n const data = await this.getClient().patch<PartialUpdateChannelAPIResponse<StreamChatGenerics>>(\n this._channelURL(),\n update,\n );\n\n const areCapabilitiesChanged =\n [...(data.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = data.channel;\n // If the capabiltities are changed, we trigger the `capabilities.changed` event.\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: data.channel.own_capabilities,\n });\n }\n return data;\n }\n\n /**\n * enableSlowMode - enable slow mode\n *\n * @param {number} coolDownInterval the cooldown interval in seconds\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async enableSlowMode(coolDownInterval: number) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n cooldown: coolDownInterval,\n });\n this.data = data.channel;\n return data;\n }\n\n /**\n * disableSlowMode - disable slow mode\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async disableSlowMode() {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n cooldown: 0,\n });\n this.data = data.channel;\n return data;\n }\n\n /**\n * delete - Delete the channel. Messages are permanently removed.\n *\n * @param {boolean} [options.hard_delete] Defines if the channel is hard deleted or not\n *\n * @return {Promise<DeleteChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async delete(options: { hard_delete?: boolean } = {}) {\n return await this.getClient().delete<DeleteChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), {\n ...options,\n });\n }\n\n /**\n * truncate - Removes all messages from the channel\n * @param {TruncateOptions<StreamChatGenerics>} [options] Defines truncation options\n * @return {Promise<TruncateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async truncate(options: TruncateOptions<StreamChatGenerics> = {}) {\n return await this.getClient().post<TruncateChannelAPIResponse<StreamChatGenerics>>(\n this._channelURL() + '/truncate',\n options,\n );\n }\n\n /**\n * acceptInvite - accept invitation to the channel\n *\n * @param {InviteOptions<StreamChatGenerics>} [options] The object to update the custom properties of this channel with\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async acceptInvite(options: InviteOptions<StreamChatGenerics> = {}) {\n return await this._update({ accept_invite: true, ...options });\n }\n\n /**\n * rejectInvite - reject invitation to the channel\n *\n * @param {InviteOptions<StreamChatGenerics>} [options] The object to update the custom properties of this channel with\n *\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async rejectInvite(options: InviteOptions<StreamChatGenerics> = {}) {\n return await this._update({ reject_invite: true, ...options });\n }\n\n /**\n * addMembers - add members to the channel\n *\n * @param {string[] | Array<NewMemberPayload<StreamChatGenerics>>} members An array of members to add to the channel\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async addMembers(\n members: string[] | Array<NewMemberPayload<StreamChatGenerics>>,\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ add_members: members, message, ...options });\n }\n\n /**\n * addModerators - add moderators to the channel\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async addModerators(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ add_moderators: members, message, ...options });\n }\n\n /**\n * assignRoles - sets member roles in a channel\n *\n * @param {{channel_role: Role, user_id: string}[]} roles List of role assignments\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async assignRoles(\n roles: { channel_role: Role; user_id: string }[],\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ assign_roles: roles, message, ...options });\n }\n\n /**\n * inviteMembers - invite members to the channel\n *\n * @param {string[] | Array<NewMemberPayload<StreamChatGenerics>>} members An array of members to invite to the channel\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async inviteMembers(\n members: string[] | Array<NewMemberPayload<StreamChatGenerics>>,\n message?: Message<StreamChatGenerics>,\n options: ChannelUpdateOptions = {},\n ) {\n return await this._update({ invites: members, message, ...options });\n }\n\n /**\n * removeMembers - remove members from channel\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async removeMembers(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ remove_members: members, message, ...options });\n }\n\n /**\n * demoteModerators - remove moderator role from channel members\n *\n * @param {string[]} members An array of member identifiers\n * @param {Message<StreamChatGenerics>} [message] Optional message object for channel members notification\n * @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async demoteModerators(members: string[], message?: Message<StreamChatGenerics>, options: ChannelUpdateOptions = {}) {\n return await this._update({ demote_moderators: members, message, ...options });\n }\n\n /**\n * _update - executes channel update request\n * @param payload Object Update Channel payload\n * @return {Promise<UpdateChannelAPIResponse<StreamChatGenerics>>} The server response\n * TODO: introduce new type instead of Object in the next major update\n */\n async _update(payload: Object) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<StreamChatGenerics>>(this._channelURL(), payload);\n this.data = data.channel;\n return data;\n }\n\n /**\n * mute - mutes the current channel\n * @param {{ user_id?: string, expiration?: string }} opts expiration in minutes or user_id\n * @return {Promise<MuteChannelAPIResponse<StreamChatGenerics>>} The server response\n *\n * example with expiration:\n * await channel.mute({expiration: moment.duration(2, 'weeks')});\n *\n * example server side:\n * await channel.mute({user_id: userId});\n *\n */\n async mute(opts: { expiration?: number; user_id?: string } = {}) {\n return await this.getClient().post<MuteChannelAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + '/moderation/mute/channel',\n { channel_cid: this.cid, ...opts },\n );\n }\n\n /**\n * unmute - mutes the current channel\n * @param {{ user_id?: string}} opts user_id\n * @return {Promise<APIResponse>} The server response\n *\n * example server side:\n * await channel.unmute({user_id: userId});\n */\n async unmute(opts: { user_id?: string } = {}) {\n return await this.getClient().post<APIResponse>(this.getClient().baseURL + '/moderation/unmute/channel', {\n channel_cid: this.cid,\n ...opts,\n });\n }\n\n /**\n * archive - archives the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.archives();\n *\n * example server side:\n * await channel.archive({user_id: userId});\n *\n */\n async archive(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw Error('A user_id is required for archiving a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { archived: true } });\n return resp.channel_member;\n }\n\n /**\n * unarchive - unarchives the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.unarchive();\n *\n * example server side:\n * await channel.unarchive({user_id: userId});\n *\n */\n async unarchive(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw Error('A user_id is required for unarchiving a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { archived: false } });\n return resp.channel_member;\n }\n\n /**\n * pin - pins the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.pin();\n *\n * example server side:\n * await channel.pin({user_id: userId});\n *\n */\n async pin(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw new Error('A user_id is required for pinning a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { pinned: true } });\n return resp.channel_member;\n }\n\n /**\n * unpin - unpins the current channel\n * @param {{ user_id?: string }} opts user_id if called server side\n * @return {Promise<ChannelMemberResponse<StreamChatGenerics>>} The server response\n *\n * example:\n * await channel.unpin();\n *\n * example server side:\n * await channel.unpin({user_id: userId});\n *\n */\n async unpin(opts: { user_id?: string } = {}) {\n const cli = this.getClient();\n const uid = opts.user_id || cli.userID;\n if (!uid) {\n throw new Error('A user_id is required for unpinning a channel');\n }\n const resp = await this.partialUpdateMember(uid, { set: { pinned: false } });\n return resp.channel_member;\n }\n\n /**\n * muteStatus - returns the mute status for the current channel\n * @return {{ muted: boolean; createdAt: Date | null; expiresAt: Date | null }} { muted: true | false, createdAt: Date | null, expiresAt: Date | null}\n */\n muteStatus(): {\n createdAt: Date | null;\n expiresAt: Date | null;\n muted: boolean;\n } {\n this._checkInitialized();\n return this.getClient()._muteStatus(this.cid);\n }\n\n sendAction(messageID: string, formData: Record<string, string>) {\n this._checkInitialized();\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return this.getClient().post<SendMessageAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/action`,\n {\n message_id: messageID,\n form_data: formData,\n id: this.id,\n type: this.type,\n },\n );\n }\n\n /**\n * keystroke - First of the typing.start and typing.stop events based on the users keystrokes.\n * Call this on every keystroke\n * @see {@link https://getstream.io/chat/docs/typing_indicators/?language=js|Docs}\n * @param {string} [parent_id] set this field to `message.id` to indicate that typing event is happening in a thread\n */\n async keystroke(parent_id?: string, options?: { user_id: string }) {\n if (!this._isTypingIndicatorsEnabled()) {\n return;\n }\n const now = new Date();\n const diff = this.lastTypingEvent && now.getTime() - this.lastTypingEvent.getTime();\n this.lastKeyStroke = now;\n this.isTyping = true;\n // send a typing.start every 2 seconds\n if (diff === null || diff > 2000) {\n this.lastTypingEvent = new Date();\n await this.sendEvent({\n type: 'typing.start',\n parent_id,\n ...(options || {}),\n } as Event<StreamChatGenerics>);\n }\n }\n\n /**\n * stopTyping - Sets last typing to null and sends the typing.stop event\n * @see {@link https://getstream.io/chat/docs/typing_indicators/?language=js|Docs}\n * @param {string} [parent_id] set this field to `message.id` to indicate that typing event is happening in a thread\n */\n async stopTyping(parent_id?: string, options?: { user_id: string }) {\n if (!this._isTypingIndicatorsEnabled()) {\n return;\n }\n this.lastTypingEvent = null;\n this.isTyping = false;\n await this.sendEvent({\n type: 'typing.stop',\n parent_id,\n ...(options || {}),\n } as Event<StreamChatGenerics>);\n }\n\n _isTypingIndicatorsEnabled(): boolean {\n if (!this.getConfig()?.typing_events) {\n return false;\n }\n return this.getClient().user?.privacy_settings?.typing_indicators?.enabled ?? true;\n }\n\n /**\n * lastMessage - return the last message, takes into account that last few messages might not be perfectly sorted\n *\n * @return {ReturnType<ChannelState<StreamChatGenerics>['formatMessage']> | undefined} Description\n */\n lastMessage(): FormatMessageResponse<StreamChatGenerics> | undefined {\n // get last 5 messages, sort, return the latest\n // get a slice of the last 5\n let min = this.state.latestMessages.length - 5;\n if (min < 0) {\n min = 0;\n }\n const max = this.state.latestMessages.length + 1;\n const messageSlice = this.state.latestMessages.slice(min, max);\n\n // sort by pk desc\n messageSlice.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());\n\n return messageSlice[0];\n }\n\n /**\n * markRead - Send the mark read event for this user, only works if the `read_events` setting is enabled\n *\n * @param {MarkReadOptions<StreamChatGenerics>} data\n * @return {Promise<EventAPIResponse<StreamChatGenerics> | null>} Description\n */\n async markRead(data: MarkReadOptions<StreamChatGenerics> = {}) {\n this._checkInitialized();\n\n if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {\n return Promise.resolve(null);\n }\n\n return await this.getClient().post<EventAPIResponse<StreamChatGenerics>>(this._channelURL() + '/read', {\n ...data,\n });\n }\n\n /**\n * markUnread - Mark the channel as unread from messageID, only works if the `read_events` setting is enabled\n *\n * @param {MarkUnreadOptions<StreamChatGenerics>} data\n * @return {APIResponse} An API response\n */\n async markUnread(data: MarkUnreadOptions<StreamChatGenerics>) {\n this._checkInitialized();\n\n if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {\n return Promise.resolve(null);\n }\n\n return await this.getClient().post<APIResponse>(this._channelURL() + '/unread', {\n ...data,\n });\n }\n\n /**\n * clean - Cleans the channel state and fires stop typing if needed\n */\n clean() {\n if (this.lastKeyStroke) {\n const now = new Date();\n const diff = now.getTime() - this.lastKeyStroke.getTime();\n if (diff > 1000 && this.isTyping) {\n logChatPromiseExecution(this.stopTyping(), 'stop typing event');\n }\n }\n\n this.state.clean();\n }\n\n /**\n * watch - Loads the initial channel state and watches for changes\n *\n * @param {ChannelQueryOptions<StreamChatGenerics>} options additional options for the query endpoint\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} The server response\n */\n async watch(options?: ChannelQueryOptions<StreamChatGenerics>) {\n const defaultOptions = {\n state: true,\n watch: true,\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n if (!this.getClient()._hasConnectionID()) {\n defaultOptions.watch = false;\n }\n\n const combined = { ...defaultOptions, ...options };\n const state = await this.query(combined, 'latest');\n this.initialized = true;\n this.data = state.channel;\n\n this._client.logger('info', `channel:watch() - started watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n return state;\n }\n\n /**\n * stopWatching - Stops watching the channel\n *\n * @return {Promise<APIResponse>} The server response\n */\n async stopWatching() {\n const response = await this.getClient().post<APIResponse>(this._channelURL() + '/stop-watching', {});\n\n this._client.logger('info', `channel:watch() - stopped watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n\n return response;\n }\n\n /**\n * getReplies - List the message replies for a parent message.\n *\n * The recommended way of working with threads is to use the Thread class.\n *\n * @param {string} parent_id The message parent id, ie the top of the thread\n * @param {MessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}\n *\n * @return {Promise<GetRepliesAPIResponse<StreamChatGenerics>>} A response with a list of messages\n */\n async getReplies(\n parent_id: string,\n options: MessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string },\n sort?: { created_at: AscDesc }[],\n ) {\n const normalizedSort = sort ? normalizeQuerySort(sort) : undefined;\n const data = await this.getClient().get<GetRepliesAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(parent_id)}/replies`,\n {\n sort: normalizedSort,\n ...options,\n },\n );\n\n // add any messages to our thread state\n if (data.messages) {\n this.state.addMessagesSorted(data.messages);\n }\n\n return data;\n }\n\n /**\n * getPinnedMessages - List list pinned messages of the channel\n *\n * @param {PinnedMessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}\n * @param {PinnedMessagesSort} sort defines sorting direction of pinned messages\n *\n * @return {Promise<GetRepliesAPIResponse<StreamChatGenerics>>} A response with a list of messages\n */\n async getPinnedMessages(\n options: PinnedMessagePaginationOptions & { user?: UserResponse<StreamChatGenerics>; user_id?: string },\n sort: PinnedMessagesSort = [],\n ) {\n return await this.getClient().get<GetRepliesAPIResponse<StreamChatGenerics>>(\n this._channelURL() + '/pinned_messages',\n {\n payload: {\n ...options,\n sort: normalizeQuerySort(sort),\n },\n },\n );\n }\n\n /**\n * getReactions - List the reactions, supports pagination\n *\n * @param {string} message_id The message id\n * @param {{ limit?: number; offset?: number }} options The pagination options\n *\n * @return {Promise<GetReactionsAPIResponse<StreamChatGenerics>>} Server response\n */\n getReactions(message_id: string, options: { limit?: number; offset?: number }) {\n return this.getClient().get<GetReactionsAPIResponse<StreamChatGenerics>>(\n this.getClient().baseURL + `/messages/${encodeURIComponent(message_id)}/reactions`,\n {\n ...options,\n },\n );\n }\n\n /**\n * getMessagesById - Retrieves a list of messages by ID\n *\n * @param {string[]} messageIds The ids of the messages to retrieve from this channel\n *\n * @return {Promise<GetMultipleMessagesAPIResponse<StreamChatGenerics>>} Server response\n */\n getMessagesById(messageIds: string[]) {\n return this.getClient().get<GetMultipleMessagesAPIResponse<StreamChatGenerics>>(this._channelURL() + '/messages', {\n ids: messageIds.join(','),\n });\n }\n\n /**\n * lastRead - returns the last time the user marked the channel as read if the user never marked the channel as read, this will return null\n * @return {Date | null | undefined}\n */\n lastRead() {\n const { userID } = this.getClient();\n if (userID) {\n return this.state.read[userID] ? this.state.read[userID].last_read : null;\n }\n }\n\n _countMessageAsUnread(message: FormatMessageResponse<StreamChatGenerics> | MessageResponse<StreamChatGenerics>) {\n if (message.shadowed) return false;\n if (message.silent) return false;\n if (message.parent_id && !message.show_in_channel) return false;\n if (message.user?.id === this.getClient().userID) return false;\n if (message.user?.id && this.getClient().userMuteStatus(message.user.id)) return false;\n\n // Return false if channel doesn't allow read events.\n if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes('read-events'))\n return false;\n\n // FIXME: see #1265, adjust and count new messages even when the channel is muted\n if (this.muteStatus().muted) return false;\n\n return true;\n }\n\n /**\n * countUnread - Count of unread messages\n *\n * @param {Date | null} [lastRead] lastRead the time that the user read a message, defaults to current user's read state\n *\n * @return {number} Unread count\n */\n countUnread(lastRead?: Date | null) {\n if (!lastRead) return this.state.unreadCount;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (message.created_at > lastRead && this._countMessageAsUnread(message)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * countUnreadMentions - Count the number of unread messages mentioning the current user\n *\n * @return {number} Unread mentions count\n */\n countUnreadMentions() {\n const lastRead = this.lastRead();\n const userID = this.getClient().userID;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (\n this._countMessageAsUnread(message) &&\n (!lastRead || message.created_at > lastRead) &&\n message.mentioned_users?.some((user) => user.id === userID)\n ) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * create - Creates a new channel\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} The Server Response\n *\n */\n create = async (options?: ChannelQueryOptions<StreamChatGenerics>) => {\n const defaultOptions = {\n ...options,\n watch: false,\n state: false,\n presence: false,\n };\n return await this.query(defaultOptions, 'latest');\n };\n\n /**\n * query - Query the API, get messages, members or other channel fields\n *\n * @param {ChannelQueryOptions<StreamChatGenerics>} options The query options\n * @param {MessageSetType} messageSetToAddToIfDoesNotExist It's possible to load disjunct sets of a channel's messages into state, use `current` to load the initial channel state or if you want to extend the currently displayed messages, use `latest` if you want to load/extend the latest messages, `new` is used for loading a specific message and it's surroundings\n *\n * @return {Promise<QueryChannelAPIResponse<StreamChatGenerics>>} Returns a query response\n */\n async query(\n options?: ChannelQueryOptions<StreamChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n let queryURL = `${this.getClient().baseURL}/channels/${encodeURIComponent(this.type)}`;\n if (this.id) {\n queryURL += `/${encodeURIComponent(this.id)}`;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<StreamChatGenerics>>(queryURL + '/query', {\n data: this._data,\n state: true,\n ...options,\n });\n\n // update the channel id if it was missing\n if (!this.id) {\n this.id = state.channel.id;\n this.cid = state.channel.cid;\n // set the channel as active...\n\n const membersStr = state.members\n .map((member) => member.user_id || member.user?.id)\n .sort()\n .join(',');\n const tempChannelCid = `${this.type}:!members-${membersStr}`;\n\n if (tempChannelCid in this.getClient().activeChannels) {\n // This gets set in `client.channel()` function, when channel is created\n // using members, not id.\n delete this.getClient().activeChannels[tempChannelCid];\n }\n\n if (!(this.cid in this.getClient().activeChannels)) {\n this.getClient().activeChannels[this.cid] = this;\n }\n }\n\n this.getClient()._addChannelConfig(state.channel);\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n messageSet.pagination = {\n ...messageSet.pagination,\n ...messageSetPagination({\n parentSet: messageSet,\n messagePaginationOptions: options?.messages,\n requestedPageSize: options?.messages?.limit ?? DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE,\n returnedPage: state.messages,\n logger: this.getClient().logger,\n }),\n };\n\n this.getClient().polls.hydratePollCache(messageSet.messages, true);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n this.getClient().dispatchEvent({\n type: 'channels.queried',\n queriedChannels: {\n channels: [state],\n isLatestMessageSet: messageSet.isLatest,\n },\n });\n\n return state;\n }\n\n /**\n * banUser - Bans a user from a channel\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} options\n * @returns {Promise<APIResponse>}\n */\n async banUser(targetUserID: string, options: BanUserOptions<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().banUser(targetUserID, {\n ...options,\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * hides the channel from queryChannels for the user until a message is added\n * If clearHistory is set to true - all messages will be removed for the user\n *\n * @param {string | null} userId\n * @param {boolean} clearHistory\n * @returns {Promise<APIResponse>}\n */\n async hide(userId: string | null = null, clearHistory = false) {\n this._checkInitialized();\n\n return await this.getClient().post<APIResponse>(`${this._channelURL()}/hide`, {\n user_id: userId,\n clear_history: clearHistory,\n });\n }\n\n /**\n * removes the hidden status for a channel\n *\n * @param {string | null} userId\n * @returns {Promise<APIResponse>}\n */\n async show(userId: string | null = null) {\n this._checkInitialized();\n return await this.getClient().post<APIResponse>(`${this._channelURL()}/show`, {\n user_id: userId,\n });\n }\n\n /**\n * unbanUser - Removes the bans for a user on a channel\n *\n * @param {string} targetUserID\n * @returns {Promise<APIResponse>}\n */\n async unbanUser(targetUserID: string) {\n this._checkInitialized();\n return await this.getClient().unbanUser(targetUserID, {\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * shadowBan - Shadow bans a user from a channel\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} options\n * @returns {Promise<APIResponse>}\n */\n async shadowBan(targetUserID: string, options: BanUserOptions<StreamChatGenerics>) {\n this._checkInitialized();\n return await this.getClient().shadowBan(targetUserID, {\n ...options,\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * removeShadowBan - Removes the shadow ban for a user on a channel\n *\n * @param {string} targetUserID\n * @returns {Promise<APIResponse>}\n */\n async removeShadowBan(targetUserID: string) {\n this._checkInitialized();\n return await this.getClient().removeShadowBan(targetUserID, {\n type: this.type,\n id: this.id,\n });\n }\n\n /**\n * createCall - creates a call for the current channel\n *\n * @param {CreateCallOptions} options\n * @returns {Promise<CreateCallResponse>}\n */\n async createCall(options: CreateCallOptions) {\n return await this.getClient().post<CreateCallResponse>(this._channelURL() + '/call', options);\n }\n\n /**\n * Cast or cancel one or more votes on a poll\n * @param pollId string The poll id\n * @param votes PollVoteData[] The votes that will be casted (or canceled in case of an empty array)\n * @returns {APIResponse & PollVoteResponse} The poll votes\n */\n async vote(messageId: string, pollId: string, vote: PollVoteData) {\n return await this.getClient().castPollVote(messageId, pollId, vote);\n }\n\n async removeVote(messageId: string, pollId: string, voteId: string) {\n return await this.getClient().removePollVote(messageId, pollId, voteId);\n }\n\n /**\n * on - Listen to events on this channel.\n *\n * channel.on('message.new', event => {console.log(\"my new message\", event, channel.state.messages)})\n * or\n * channel.on(event => {console.log(event.type)})\n *\n * @param {EventHandler<StreamChatGenerics> | EventTypes} callbackOrString The event type to listen for (optional)\n * @param {EventHandler<StreamChatGenerics>} [callbackOrNothing] The callback to call\n */\n on(eventType: EventTypes, callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<StreamChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this._client.logger('info', `Attaching listener for ${key} event on channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key].push(callback);\n\n return {\n unsubscribe: () => {\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n /**\n * off - Remove the event handler\n *\n */\n off(eventType: EventTypes, callback: EventHandler<StreamChatGenerics>): void;\n off(callback: EventHandler<StreamChatGenerics>): void;\n off(\n callbackOrString: EventHandler<StreamChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): void {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _handleChannelEvent(event: Event<StreamChatGenerics>) {\n const channel = this;\n this._client.logger(\n 'info',\n `channel:_handleChannelEvent - Received event of type { ${event.type} } on ${this.cid}`,\n {\n tags: ['event', 'channel'],\n channel: this,\n },\n );\n\n const channelState = channel.state;\n switch (event.type) {\n case 'typing.start':\n if (event.user?.id) {\n channelState.typing[event.user.id] = event;\n }\n break;\n case 'typing.stop':\n if (event.user?.id) {\n delete channelState.typing[event.user.id];\n }\n break;\n case 'message.read':\n if (event.user?.id && event.created_at) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at),\n last_read_message_id: event.last_read_message_id,\n user: event.user,\n unread_messages: 0,\n };\n\n if (event.user?.id === this.getClient().user?.id) {\n channelState.unreadCount = 0;\n }\n }\n break;\n case 'user.watching.start':\n case 'user.updated':\n if (event.user?.id) {\n channelState.watchers[event.user.id] = event.user;\n }\n break;\n case 'user.watching.stop':\n if (event.user?.id) {\n delete channelState.watchers[event.user.id];\n }\n break;\n case 'message.deleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n if (event.hard_delete) channelState.removeMessage(event.message);\n else channelState.addMessageSorted(event.message, false, false);\n\n channelState.removeQuotedMessageReferences(event.message);\n\n if (event.message.pinned) {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.new':\n if (event.message) {\n /* if message belongs to current user, always assume timestamp is changed to filter it out and add again to avoid duplication */\n const ownMessage = event.user?.id === this.getClient().user?.id;\n const isThreadMessage = event.message.parent_id && !event.message.show_in_channel;\n\n if (this.state.isUpToDate || isThreadMessage) {\n channelState.addMessageSorted(event.message, ownMessage);\n }\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n\n // do not increase the unread count - the back-end does not increase the count neither in the following cases:\n // 1. the message is mine\n // 2. the message is a thread reply from any user\n const preventUnreadCountUpdate = ownMessage || isThreadMessage;\n if (preventUnreadCountUpdate) break;\n\n if (event.user?.id) {\n for (const userId in channelState.read) {\n if (userId === event.user.id) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at as string),\n user: event.user,\n unread_messages: 0,\n };\n } else {\n channelState.read[userId].unread_messages += 1;\n }\n }\n }\n\n if (this._countMessageAsUnread(event.message)) {\n channelState.unreadCount = channelState.unreadCount + 1;\n }\n }\n break;\n case 'message.updated':\n case 'message.undeleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n channelState.addMessageSorted(event.message, false, false);\n channelState._updateQuotedMessageReferences({ message: event.message });\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n } else {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'channel.truncated':\n if (event.channel?.truncated_at) {\n const truncatedAt = +new Date(event.channel.truncated_at);\n\n channelState.messageSets.forEach((messageSet, messageSetIndex) => {\n messageSet.messages.forEach(({ created_at: createdAt, id }) => {\n if (truncatedAt > +createdAt) channelState.removeMessage({ id, messageSetIndex });\n });\n });\n\n channelState.pinnedMessages.forEach(({ id, created_at: createdAt }) => {\n if (truncatedAt > +createdAt)\n channelState.removePinnedMessage({ id } as MessageResponse<StreamChatGenerics>);\n });\n } else {\n channelState.clearMessages();\n }\n\n channelState.unreadCount = 0;\n // system messages don't increment unread counts\n if (event.message) {\n channelState.addMessageSorted(event.message);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n }\n break;\n case 'member.added':\n case 'member.updated':\n if (event.member?.user_id) {\n channelState.members = {\n ...channelState.members,\n [event.member.user_id]: event.member,\n };\n }\n break;\n case 'member.removed':\n if (event.user?.id) {\n const newMembers = {\n ...channelState.members,\n };\n\n delete newMembers[event.user.id];\n\n channelState.members = newMembers;\n }\n break;\n case 'notification.mark_unread': {\n const ownMessage = event.user?.id === this.getClient().user?.id;\n if (!(ownMessage && event.user)) break;\n\n const unreadCount = event.unread_messages ?? 0;\n\n channelState.read[event.user.id] = {\n first_unread_message_id: event.first_unread_message_id,\n last_read: new Date(event.last_read_at as string),\n last_read_message_id: event.last_read_message_id,\n user: event.user,\n unread_messages: unreadCount,\n };\n\n channelState.unreadCount = unreadCount;\n break;\n }\n case 'channel.updated':\n if (event.channel) {\n const isFrozenChanged = event.channel?.frozen !== undefined && event.channel.frozen !== channel.data?.frozen;\n if (isFrozenChanged) {\n this.query({ state: false, messages: { limit: 0 }, watchers: { limit: 0 } });\n }\n channel.data = {\n ...event.channel,\n hidden: event.channel?.hidden ?? channel.data?.hidden,\n own_capabilities: event.channel?.own_capabilities ?? channel.data?.own_capabilities,\n };\n }\n break;\n case 'reaction.new':\n if (event.message && event.reaction) {\n event.message = channelState.addReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.deleted':\n if (event.reaction) {\n event.message = channelState.removeReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.updated':\n if (event.reaction) {\n // assuming reaction.updated is only called if enforce_unique is true\n event.message = channelState.addReaction(event.reaction, event.message, true);\n }\n break;\n case 'channel.hidden':\n channel.data = { ...channel.data, hidden: true };\n if (event.clear_history) {\n channelState.clearMessages();\n }\n break;\n case 'channel.visible':\n channel.data = { ...channel.data, hidden: false };\n break;\n case 'user.banned':\n if (!event.user?.id) break;\n channelState.members[event.user.id] = {\n ...(channelState.members[event.user.id] || {}),\n shadow_banned: !!event.shadow,\n banned: !event.shadow,\n user: { ...(channelState.members[event.user.id]?.user || {}), ...event.user },\n };\n break;\n case 'user.unbanned':\n if (!event.user?.id) break;\n channelState.members[event.user.id] = {\n ...(channelState.members[event.user.id] || {}),\n shadow_banned: false,\n banned: false,\n user: { ...(channelState.members[event.user.id]?.user || {}), ...event.user },\n };\n break;\n default:\n }\n\n // any event can send over the online count\n if (event.watcher_count !== undefined) {\n channel.state.watcher_count = event.watcher_count;\n }\n }\n\n _callChannelListeners = (event: Event<StreamChatGenerics>) => {\n const channel = this;\n // gather and call the listeners\n const listeners = [];\n if (channel.listeners.all) {\n listeners.push(...channel.listeners.all);\n }\n if (channel.listeners[event.type]) {\n listeners.push(...channel.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n if (typeof listener !== 'string') {\n listener(event);\n }\n }\n };\n\n /**\n * _channelURL - Returns the channel url\n *\n * @return {string} The channel url\n */\n _channelURL = () => {\n if (!this.id) {\n throw new Error('channel id is not defined');\n }\n return `${this.getClient().baseURL}/channels/${encodeURIComponent(this.type)}/${encodeURIComponent(this.id)}`;\n };\n\n _checkInitialized() {\n if (!this.initialized && !this.offlineMode && !this.getClient()._isUsingServerAuth()) {\n throw Error(\n `Channel ${this.cid} hasn't been initialized yet. Make sure to call .watch() and wait for it to resolve`,\n );\n }\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _initializeState(\n state: ChannelAPIResponse<StreamChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n const { state: clientState, user, userID } = this.getClient();\n\n // add the Users\n if (state.members) {\n for (const member of state.members) {\n if (member.user) {\n clientState.updateUserReference(member.user, this.cid);\n }\n }\n }\n\n this.state.membership = state.membership || {};\n\n const messages = state.messages || [];\n if (!this.state.messages) {\n this.state.initMessages();\n }\n const { messageSet } = this.state.addMessagesSorted(messages, false, true, true, messageSetToAddToIfDoesNotExist);\n\n if (!this.state.pinnedMessages) {\n this.state.pinnedMessages = [];\n }\n this.state.addPinnedMessages(state.pinned_messages || []);\n if (state.pending_messages) {\n this.state.pending_messages = state.pending_messages;\n }\n if (state.watcher_count !== undefined) {\n this.state.watcher_count = state.watcher_count;\n }\n // convert the arrays into objects for easier syncing...\n if (state.watchers) {\n for (const watcher of state.watchers) {\n if (watcher) {\n clientState.updateUserReference(watcher, this.cid);\n this.state.watchers[watcher.id] = watcher;\n }\n }\n }\n\n // initialize read state to last message or current time if the channel is empty\n // if the user is a member, this value will be overwritten later on otherwise this ensures\n // that everything up to this point is not marked as unread\n if (userID != null) {\n const last_read = this.state.last_message_at || new Date();\n if (user) {\n this.state.read[user.id] = {\n user,\n last_read,\n unread_messages: 0,\n };\n }\n }\n\n // apply read state if part of the state\n if (state.read) {\n for (const read of state.read) {\n this.state.read[read.user.id] = {\n last_read: new Date(read.last_read),\n last_read_message_id: read.last_read_message_id,\n unread_messages: read.unread_messages ?? 0,\n user: read.user,\n };\n\n if (read.user.id === user?.id) {\n this.state.unreadCount = this.state.read[read.user.id].unread_messages;\n }\n }\n }\n\n if (state.members) {\n this._hydrateMembers(state.members);\n }\n\n return {\n messageSet,\n };\n }\n\n _extendEventWithOwnReactions(event: Event<StreamChatGenerics>) {\n if (!event.message) {\n return;\n }\n const message = this.state.findMessage(event.message.id, event.message.parent_id);\n if (message) {\n event.message.own_reactions = message.own_reactions;\n }\n }\n\n _hydrateMembers(members: ChannelMemberResponse<StreamChatGenerics>[]) {\n this.state.members = members.reduce((acc, member) => {\n if (member.user) {\n acc[member.user.id] = member;\n }\n return acc;\n }, {} as ChannelState<StreamChatGenerics>['members']);\n }\n\n _disconnect() {\n this._client.logger('info', `channel:disconnect() - Disconnecting the channel ${this.cid}`, {\n tags: ['connection', 'channel'],\n channel: this,\n });\n\n this.disconnected = true;\n this.state.setIsUpToDate(false);\n }\n}\n","import { UserResponse, ExtendableGenerics, DefaultGenerics } from './types';\n\n/**\n * ClientState - A container class for the client state.\n */\nexport class ClientState<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n users: {\n [key: string]: UserResponse<StreamChatGenerics>;\n };\n userChannelReferences: { [key: string]: { [key: string]: boolean } };\n constructor() {\n // show the status for a certain user...\n // ie online, offline etc\n this.users = {};\n // store which channels contain references to the specified user...\n this.userChannelReferences = {};\n }\n\n updateUsers(users: UserResponse<StreamChatGenerics>[]) {\n for (const user of users) {\n this.updateUser(user);\n }\n }\n\n updateUser(user?: UserResponse<StreamChatGenerics>) {\n if (user != null) {\n this.users[user.id] = user;\n }\n }\n\n updateUserReference(user: UserResponse<StreamChatGenerics>, channelID: string) {\n if (user == null) {\n return;\n }\n this.updateUser(user);\n if (!this.userChannelReferences[user.id]) {\n this.userChannelReferences[user.id] = {};\n }\n this.userChannelReferences[user.id][channelID] = true;\n }\n\n deleteAllChannelReference(channelID: string) {\n for (const userID in this.userChannelReferences) {\n delete this.userChannelReferences[userID][channelID];\n }\n }\n}\n","// https://github.com/maxogden/websocket-stream/blob/48dc3ddf943e5ada668c31ccd94e9186f02fafbd/ws-fallback.js\n\nvar ws = null\n\nif (typeof WebSocket !== 'undefined') {\n ws = WebSocket\n} else if (typeof MozWebSocket !== 'undefined') {\n ws = MozWebSocket\n} else if (typeof global !== 'undefined') {\n ws = global.WebSocket || global.MozWebSocket\n} else if (typeof window !== 'undefined') {\n ws = window.WebSocket || window.MozWebSocket\n} else if (typeof self !== 'undefined') {\n ws = self.WebSocket || self.MozWebSocket\n}\n\nmodule.exports = ws\n","import axios from 'axios';\nimport { StableWSConnection } from './connection';\nimport { randomId, sleep } from './utils';\n\nexport type InsightTypes = 'ws_fatal' | 'ws_success_after_failure' | 'http_hi_failed';\nexport class InsightMetrics {\n connectionStartTimestamp: number | null;\n wsConsecutiveFailures: number;\n wsTotalFailures: number;\n instanceClientId: string;\n\n constructor() {\n this.connectionStartTimestamp = null;\n this.wsTotalFailures = 0;\n this.wsConsecutiveFailures = 0;\n this.instanceClientId = randomId();\n }\n}\n\n/**\n * postInsights is not supposed to be used by end users directly within chat application, and thus is kept isolated\n * from all the client/connection code/logic.\n *\n * @param insightType\n * @param insights\n */\nexport const postInsights = async (insightType: InsightTypes, insights: Record<string, unknown>) => {\n const maxAttempts = 3;\n for (let i = 0; i < maxAttempts; i++) {\n try {\n await axios.post(`https://chat-insights.getstream.io/insights/${insightType}`, insights);\n } catch (e) {\n await sleep((i + 1) * 3000);\n continue;\n }\n break;\n }\n};\n\nexport function buildWsFatalInsight(connection: StableWSConnection, event: Record<string, unknown>) {\n return {\n ...event,\n ...buildWsBaseInsight(connection),\n };\n}\n\nfunction buildWsBaseInsight(connection: StableWSConnection) {\n const { client } = connection;\n return {\n ready_state: connection.ws?.readyState,\n url: connection._buildUrl(),\n api_key: client.key,\n start_ts: client.insightMetrics.connectionStartTimestamp,\n end_ts: new Date().getTime(),\n auth_type: client.getAuthType(),\n token: client.tokenManager.token,\n user_id: client.userID,\n user_details: client._user,\n device: client.options.device,\n client_id: connection.connectionID,\n ws_details: connection.ws,\n ws_consecutive_failures: client.insightMetrics.wsConsecutiveFailures,\n ws_total_failures: client.insightMetrics.wsTotalFailures,\n request_id: connection.requestID,\n online: typeof navigator !== 'undefined' ? navigator?.onLine : null,\n user_agent: typeof navigator !== 'undefined' ? navigator?.userAgent : null,\n instance_client_id: client.insightMetrics.instanceClientId,\n };\n}\n\nexport function buildWsSuccessAfterFailureInsight(connection: StableWSConnection) {\n return buildWsBaseInsight(connection);\n}\n","import WebSocket from 'isomorphic-ws';\nimport {\n chatCodes,\n convertErrorToJson,\n sleep,\n retryInterval,\n randomId,\n removeConnectionEventListeners,\n addConnectionEventListeners,\n} from './utils';\nimport { buildWsFatalInsight, buildWsSuccessAfterFailureInsight, postInsights } from './insights';\nimport { ConnectAPIResponse, ConnectionOpen, ExtendableGenerics, DefaultGenerics, UR, LogLevel } from './types';\nimport { StreamChat } from './client';\n\n// Type guards to check WebSocket error type\nconst isCloseEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.CloseEvent =>\n (res as WebSocket.CloseEvent).code !== undefined;\n\nconst isErrorEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.ErrorEvent =>\n (res as WebSocket.ErrorEvent).error !== undefined;\n\n/**\n * StableWSConnection - A WS connection that reconnects upon failure.\n * - the browser will sometimes report that you're online or offline\n * - the WS connection can break and fail (there is a 30s health check)\n * - sometimes your WS connection will seem to work while the user is in fact offline\n * - to speed up online/offline detection you can use the window.addEventListener('offline');\n *\n * There are 4 ways in which a connection can become unhealthy:\n * - websocket.onerror is called\n * - websocket.onclose is called\n * - the health check fails and no event is received for ~40 seconds\n * - the browser indicates the connection is now offline\n *\n * There are 2 assumptions we make about the server:\n * - state can be recovered by querying the channel again\n * - if the servers fails to publish a message to the client, the WS connection is destroyed\n */\nexport class StableWSConnection<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n // global from constructor\n client: StreamChat<StreamChatGenerics>;\n\n // local vars\n connectionID?: string;\n connectionOpen?: ConnectAPIResponse<StreamChatGenerics>;\n consecutiveFailures: number;\n pingInterval: number;\n healthCheckTimeoutRef?: NodeJS.Timeout;\n isConnecting: boolean;\n isDisconnected: boolean;\n isHealthy: boolean;\n isResolved?: boolean;\n lastEvent: Date | null;\n connectionCheckTimeout: number;\n connectionCheckTimeoutRef?: NodeJS.Timeout;\n rejectPromise?: (\n reason?: Error & { code?: string | number; isWSFailure?: boolean; StatusCode?: string | number },\n ) => void;\n requestID: string | undefined;\n resolvePromise?: (value: ConnectionOpen<StreamChatGenerics>) => void;\n totalFailures: number;\n ws?: WebSocket;\n wsID: number;\n\n constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {\n /** StreamChat client */\n this.client = client;\n /** consecutive failures influence the duration of the timeout */\n this.consecutiveFailures = 0;\n /** keep track of the total number of failures */\n this.totalFailures = 0;\n /** We only make 1 attempt to reconnect at the same time.. */\n this.isConnecting = false;\n /** To avoid reconnect if client is disconnected */\n this.isDisconnected = false;\n /** Boolean that indicates if the connection promise is resolved */\n this.isResolved = false;\n /** Boolean that indicates if we have a working connection to the server */\n this.isHealthy = false;\n /** Incremented when a new WS connection is made */\n this.wsID = 1;\n /** Store the last event time for health checks */\n this.lastEvent = null;\n /** Send a health check message every 25 seconds */\n this.pingInterval = 25 * 1000;\n this.connectionCheckTimeout = this.pingInterval + 10 * 1000;\n\n addConnectionEventListeners(this.onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'connection:' + msg, { tags: ['connection'], ...extra });\n }\n\n setClient(client: StreamChat<StreamChatGenerics>) {\n this.client = client;\n }\n\n /**\n * connect - Connect to the WS URL\n * the default 15s timeout allows between 2~3 tries\n * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received\n */\n async connect(timeout = 15000) {\n if (this.isConnecting) {\n throw Error(`You've called connect twice, can only attempt 1 connection at the time`);\n }\n\n this.isDisconnected = false;\n\n try {\n const healthCheck = await this._connect();\n this.consecutiveFailures = 0;\n\n this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);\n } catch (error) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n if (error.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {\n this._log('connect() - WS failure due to expired token, so going to try to reload token and reconnect');\n this._reconnect({ refreshToken: true });\n } else if (!error.isWSFailure) {\n // API rejected the connection and we should not retry\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n }\n\n return await this._waitForHealthy(timeout);\n }\n\n /**\n * _waitForHealthy polls the promise connection to see if its resolved until it times out\n * the default 15s timeout allows between 2~3 tries\n * @param timeout duration(ms)\n */\n async _waitForHealthy(timeout = 15000) {\n return Promise.race([\n (async () => {\n const interval = 50; // ms\n for (let i = 0; i <= timeout; i += interval) {\n try {\n return await this.connectionOpen;\n } catch (error) {\n if (i === timeout) {\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n await sleep(interval);\n }\n }\n })(),\n (async () => {\n await sleep(timeout);\n this.isConnecting = false;\n throw new Error(\n JSON.stringify({\n code: '',\n StatusCode: '',\n message: 'initial WS connection could not be established',\n isWSFailure: true,\n }),\n );\n })(),\n ]);\n }\n\n /**\n * Builds and returns the url for websocket.\n * @private\n * @returns url string\n */\n _buildUrl = () => {\n const qs = encodeURIComponent(this.client._buildWSPayload(this.requestID));\n const token = this.client.tokenManager.getToken();\n\n return `${this.client.wsBaseURL}/connect?json=${qs}&api_key=${\n this.client.key\n }&authorization=${token}&stream-auth-type=${this.client.getAuthType()}&X-Stream-Client=${this.client.getUserAgent()}`;\n };\n\n /**\n * disconnect - Disconnect the connection and doesn't recover...\n *\n */\n disconnect(timeout?: number) {\n this._log(`disconnect() - Closing the websocket connection for wsID ${this.wsID}`);\n\n this.wsID += 1;\n this.isConnecting = false;\n this.isDisconnected = true;\n\n // start by removing all the listeners\n if (this.healthCheckTimeoutRef) {\n clearInterval(this.healthCheckTimeoutRef);\n }\n if (this.connectionCheckTimeoutRef) {\n clearInterval(this.connectionCheckTimeoutRef);\n }\n\n removeConnectionEventListeners(this.onlineStatusChanged);\n\n this.isHealthy = false;\n\n // remove ws handlers...\n if (this.ws && this.ws.removeAllListeners) {\n this.ws.removeAllListeners();\n }\n\n let isClosedPromise: Promise<void>;\n // and finally close...\n // Assigning to local here because we will remove it from this before the\n // promise resolves.\n const { ws } = this;\n if (ws && ws.close && ws.readyState === ws.OPEN) {\n isClosedPromise = new Promise((resolve) => {\n const onclose = (event: WebSocket.CloseEvent) => {\n this._log(`disconnect() - resolving isClosedPromise ${event ? 'with' : 'without'} close frame`, { event });\n resolve();\n };\n\n ws.onclose = onclose;\n // In case we don't receive close frame websocket server in time,\n // lets not wait for more than 1 seconds.\n setTimeout(onclose, timeout != null ? timeout : 1000);\n });\n\n this._log(`disconnect() - Manually closed connection by calling client.disconnect()`);\n\n ws.close(chatCodes.WS_CLOSED_SUCCESS, 'Manually closed connection by calling client.disconnect()');\n } else {\n this._log(`disconnect() - ws connection doesn't exist or it is already closed.`);\n isClosedPromise = Promise.resolve();\n }\n\n delete this.ws;\n\n return isClosedPromise;\n }\n\n /**\n * _connect - Connect to the WS endpoint\n *\n * @return {ConnectAPIResponse<ChannelType, CommandType, UserType>} Promise that completes once the first health check message is received\n */\n async _connect() {\n if (this.isConnecting || (this.isDisconnected && this.client.options.enableWSFallback)) return; // simply ignore _connect if it's currently trying to connect\n this.isConnecting = true;\n this.requestID = randomId();\n this.client.insightMetrics.connectionStartTimestamp = new Date().getTime();\n let isTokenReady = false;\n try {\n this._log(`_connect() - waiting for token`);\n await this.client.tokenManager.tokenReady();\n isTokenReady = true;\n } catch (e) {\n // token provider has failed before, so try again\n }\n\n try {\n if (!isTokenReady) {\n this._log(`_connect() - tokenProvider failed before, so going to retry`);\n await this.client.tokenManager.loadToken();\n }\n\n this._setupConnectionPromise();\n const wsURL = this._buildUrl();\n this._log(`_connect() - Connecting to ${wsURL}`, { wsURL, requestID: this.requestID });\n this.ws = new WebSocket(wsURL);\n this.ws.onopen = this.onopen.bind(this, this.wsID);\n this.ws.onclose = this.onclose.bind(this, this.wsID);\n this.ws.onerror = this.onerror.bind(this, this.wsID);\n this.ws.onmessage = this.onmessage.bind(this, this.wsID);\n const response = await this.connectionOpen;\n this.isConnecting = false;\n\n if (response) {\n this.connectionID = response.connection_id;\n if (this.client.insightMetrics.wsConsecutiveFailures > 0 && this.client.options.enableInsights) {\n postInsights(\n 'ws_success_after_failure',\n buildWsSuccessAfterFailureInsight((this as unknown) as StableWSConnection),\n );\n this.client.insightMetrics.wsConsecutiveFailures = 0;\n }\n return response;\n }\n } catch (err) {\n this.isConnecting = false;\n this._log(`_connect() - Error - `, err);\n if (this.client.options.enableInsights) {\n this.client.insightMetrics.wsConsecutiveFailures++;\n this.client.insightMetrics.wsTotalFailures++;\n\n const insights = buildWsFatalInsight((this as unknown) as StableWSConnection, convertErrorToJson(err as Error));\n postInsights?.('ws_fatal', insights);\n }\n throw err;\n }\n }\n\n /**\n * _reconnect - Retry the connection to WS endpoint\n *\n * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available\n *\n * - `interval`\t{int}\t\t\tnumber of ms that function should wait before reconnecting\n * - `refreshToken` {boolean}\treload/refresh user token be refreshed before attempting reconnection.\n */\n async _reconnect(options: { interval?: number; refreshToken?: boolean } = {}): Promise<void> {\n this._log('_reconnect() - Initiating the reconnect');\n\n // only allow 1 connection at the time\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (1) since already connecting or healthy');\n return;\n }\n\n // reconnect in case of on error or on close\n // also reconnect if the health check cycle fails\n let interval = options.interval;\n if (!interval) {\n interval = retryInterval(this.consecutiveFailures);\n }\n // reconnect, or try again after a little while...\n await sleep(interval);\n\n // Check once again if by some other call to _reconnect is active or connection is\n // already restored, then no need to proceed.\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (2) since already connecting or healthy');\n return;\n }\n\n if (this.isDisconnected && this.client.options.enableWSFallback) {\n this._log('_reconnect() - Abort (3) since disconnect() is called');\n return;\n }\n\n this._log('_reconnect() - Destroying current WS connection');\n\n // cleanup the old connection\n this._destroyCurrentWSConnection();\n\n if (options.refreshToken) {\n await this.client.tokenManager.loadToken();\n }\n\n try {\n await this._connect();\n this._log('_reconnect() - Waiting for recoverCallBack');\n await this.client.recoverState();\n this._log('_reconnect() - Finished recoverCallBack');\n\n this.consecutiveFailures = 0;\n } catch (error) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n if (error.code === chatCodes.TOKEN_EXPIRED && !this.client.tokenManager.isStatic()) {\n this._log('_reconnect() - WS failure due to expired token, so going to try to reload token and reconnect');\n\n return this._reconnect({ refreshToken: true });\n }\n\n // reconnect on WS failures, don't reconnect if there is a code bug\n if (error.isWSFailure) {\n this._log('_reconnect() - WS failure, so going to try to reconnect');\n\n this._reconnect();\n }\n }\n this._log('_reconnect() - == END ==');\n }\n\n /**\n * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.\n *\n * @param {Event} event Event with type online or offline\n *\n */\n onlineStatusChanged = (event: Event) => {\n if (event.type === 'offline') {\n // mark the connection as down\n this._log('onlineStatusChanged() - Status changing to offline');\n this._setHealth(false);\n } else if (event.type === 'online') {\n // retry right now...\n // We check this.isHealthy, not sure if it's always\n // smart to create a new WS connection if the old one is still up and running.\n // it's possible we didn't miss any messages, so this process is just expensive and not needed.\n this._log(`onlineStatusChanged() - Status changing to online. isHealthy: ${this.isHealthy}`);\n if (!this.isHealthy) {\n this._reconnect({ interval: 10 });\n }\n }\n };\n\n onopen = (wsID: number) => {\n if (this.wsID !== wsID) return;\n\n this._log('onopen() - onopen callback', { wsID });\n };\n\n onmessage = (wsID: number, event: WebSocket.MessageEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onmessage() - onmessage callback', { event, wsID });\n const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;\n\n // we wait till the first message before we consider the connection open..\n // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately\n // after that a ws.onclose..\n if (!this.isResolved && data) {\n this.isResolved = true;\n if (data.error) {\n this.rejectPromise?.(this._errorFromWSEvent(data, false));\n return;\n }\n\n this.resolvePromise?.(data);\n this._setHealth(true);\n }\n\n // trigger the event..\n this.lastEvent = new Date();\n\n if (data && data.type === 'health.check') {\n this.scheduleNextPing();\n }\n\n this.client.handleEvent(event);\n this.scheduleConnectionCheck();\n };\n\n onclose = (wsID: number, event: WebSocket.CloseEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onclose() - onclose callback - ' + event.code, { event, wsID });\n\n if (event.code === chatCodes.WS_CLOSED_SUCCESS) {\n // this is a permanent error raised by stream..\n // usually caused by invalid auth details\n const error = new Error(`WS connection reject with error ${event.reason}`) as Error & WebSocket.CloseEvent;\n\n error.reason = event.reason;\n error.code = event.code;\n error.wasClean = event.wasClean;\n error.target = event.target;\n\n this.rejectPromise?.(error);\n this._log(`onclose() - WS connection reject with error ${event.reason}`, { event });\n } else {\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n\n this._log(`onclose() - WS connection closed. Calling reconnect ...`, { event });\n\n // reconnect if its an abnormal failure\n this._reconnect();\n }\n };\n\n onerror = (wsID: number, event: WebSocket.ErrorEvent) => {\n if (this.wsID !== wsID) return;\n\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n this._log(`onerror() - WS connection resulted into error`, { event });\n\n this._reconnect();\n };\n\n /**\n * _setHealth - Sets the connection to healthy or unhealthy.\n * Broadcasts an event in case the connection status changed.\n *\n * @param {boolean} healthy boolean indicating if the connection is healthy or not\n *\n */\n _setHealth = (healthy: boolean) => {\n if (healthy === this.isHealthy) return;\n\n this.isHealthy = healthy;\n\n if (this.isHealthy) {\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n return;\n }\n\n // we're offline, wait few seconds and fire and event if still offline\n setTimeout(() => {\n if (this.isHealthy) return;\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n }, 5000);\n };\n\n /**\n * _errorFromWSEvent - Creates an error object for the WS event\n *\n */\n _errorFromWSEvent = (event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent, isWSFailure = true) => {\n let code;\n let statusCode;\n let message;\n if (isCloseEvent(event)) {\n code = event.code;\n statusCode = 'unknown';\n message = event.reason;\n }\n\n if (isErrorEvent(event)) {\n code = event.error.code;\n statusCode = event.error.StatusCode;\n message = event.error.message;\n }\n\n // Keeping this `warn` level log, to avoid cluttering of error logs from ws failures.\n this._log(`_errorFromWSEvent() - WS failed with code ${code}`, { event }, 'warn');\n\n const error = new Error(`WS failed with code ${code} and reason - ${message}`) as Error & {\n code?: string | number;\n isWSFailure?: boolean;\n StatusCode?: string | number;\n };\n error.code = code;\n /**\n * StatusCode does not exist on any event types but has been left\n * as is to preserve JS functionality during the TS implementation\n */\n error.StatusCode = statusCode;\n error.isWSFailure = isWSFailure;\n return error;\n };\n\n /**\n * _destroyCurrentWSConnection - Removes the current WS connection\n *\n */\n _destroyCurrentWSConnection() {\n // increment the ID, meaning we will ignore all messages from the old\n // ws connection from now on.\n this.wsID += 1;\n\n try {\n this?.ws?.removeAllListeners();\n this?.ws?.close();\n } catch (e) {\n // we don't care\n }\n }\n\n /**\n * _setupPromise - sets up the this.connectOpen promise\n */\n _setupConnectionPromise = () => {\n this.isResolved = false;\n /** a promise that is resolved once ws.open is called */\n this.connectionOpen = new Promise<ConnectionOpen<StreamChatGenerics>>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n };\n\n /**\n * Schedules a next health check ping for websocket.\n */\n scheduleNextPing = () => {\n if (this.healthCheckTimeoutRef) {\n clearTimeout(this.healthCheckTimeoutRef);\n }\n\n // 30 seconds is the recommended interval (messenger uses this)\n this.healthCheckTimeoutRef = setTimeout(() => {\n // send the healthcheck.., server replies with a health check event\n const data = [{ type: 'health.check', client_id: this.client.clientID }];\n // try to send on the connection\n try {\n this.ws?.send(JSON.stringify(data));\n } catch (e) {\n // error will already be detected elsewhere\n }\n }, this.pingInterval);\n };\n\n /**\n * scheduleConnectionCheck - schedules a check for time difference between last received event and now.\n * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs\n * to be reconnected.\n */\n scheduleConnectionCheck = () => {\n if (this.connectionCheckTimeoutRef) {\n clearTimeout(this.connectionCheckTimeoutRef);\n }\n\n this.connectionCheckTimeoutRef = setTimeout(() => {\n const now = new Date();\n if (this.lastEvent && now.getTime() - this.lastEvent.getTime() > this.connectionCheckTimeout) {\n this._log('scheduleConnectionCheck - going to reconnect');\n this._setHealth(false);\n this._reconnect();\n }\n }, this.connectionCheckTimeout);\n };\n}\n","import jwt, { Secret, SignOptions } from 'jsonwebtoken';\nimport crypto from 'crypto';\nimport { encodeBase64, decodeBase64 } from './base64';\nimport { UR } from './types';\n\n/**\n * Creates the JWT token that can be used for a UserSession\n * @method JWTUserToken\n * @memberof signing\n * @private\n * @param {Secret} apiSecret - API Secret key\n * @param {string} userId - The user_id key in the JWT payload\n * @param {UR} [extraData] - Extra that should be part of the JWT token\n * @param {SignOptions} [jwtOptions] - Options that can be past to jwt.sign\n * @return {string} JWT Token\n */\nexport function JWTUserToken(apiSecret: Secret, userId: string, extraData: UR = {}, jwtOptions: SignOptions = {}) {\n if (typeof userId !== 'string') {\n throw new TypeError('userId should be a string');\n }\n\n const payload: { user_id: string } & UR = {\n user_id: userId,\n ...extraData,\n };\n\n // make sure we return a clear error when jwt is shimmed (ie. browser build)\n if (jwt == null || jwt.sign == null) {\n throw Error(\n `Unable to find jwt crypto, if you are getting this error is probably because you are trying to generate tokens on browser or React Native (or other environment where crypto functions are not available). Please Note: token should only be generated server-side.`,\n );\n }\n\n const opts: SignOptions = Object.assign({ algorithm: 'HS256', noTimestamp: true }, jwtOptions);\n\n if (payload.iat) {\n opts.noTimestamp = false;\n }\n return jwt.sign(payload, apiSecret, opts);\n}\n\nexport function JWTServerToken(apiSecret: Secret, jwtOptions: SignOptions = {}) {\n const payload = {\n server: true,\n };\n\n const opts: SignOptions = Object.assign({ algorithm: 'HS256', noTimestamp: true }, jwtOptions);\n return jwt.sign(payload, apiSecret, opts);\n}\n\nexport function UserFromToken(token: string) {\n const fragments = token.split('.');\n if (fragments.length !== 3) {\n return '';\n }\n const b64Payload = fragments[1];\n const payload = decodeBase64(b64Payload);\n const data = JSON.parse(payload);\n return data.user_id as string;\n}\n\n/**\n *\n * @param {string} userId the id of the user\n * @return {string}\n */\nexport function DevToken(userId: string) {\n return [\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', //{\"alg\": \"HS256\", \"typ\": \"JWT\"}\n encodeBase64(JSON.stringify({ user_id: userId })),\n 'devtoken', // hardcoded signature\n ].join('.');\n}\n\n/**\n *\n * @param {string | Buffer} body the signed message\n * @param {string} secret the shared secret used to generate the signature (Stream API secret)\n * @param {string} signature the signature to validate\n * @return {boolean}\n */\nexport function CheckSignature(body: string | Buffer, secret: string, signature: string) {\n const key = Buffer.from(secret, 'utf8');\n const hash = crypto.createHmac('sha256', key).update(body).digest('hex');\n\n try {\n return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));\n } catch {\n return false;\n }\n}\n","export default null;","export default null;","import axios, { AxiosRequestConfig, CancelTokenSource } from 'axios';\nimport { StreamChat } from './client';\nimport { addConnectionEventListeners, removeConnectionEventListeners, retryInterval, sleep } from './utils';\nimport { isAPIError, isConnectionIDError, isErrorRetryable } from './errors';\nimport { ConnectionOpen, Event, UR, ExtendableGenerics, DefaultGenerics, LogLevel } from './types';\n\nexport enum ConnectionState {\n Closed = 'CLOSED',\n Connected = 'CONNECTED',\n Connecting = 'CONNECTING',\n Disconnected = 'DISCONNECTED',\n Init = 'INIT',\n}\n\nexport class WSConnectionFallback<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n client: StreamChat<StreamChatGenerics>;\n state: ConnectionState;\n consecutiveFailures: number;\n connectionID?: string;\n cancelToken?: CancelTokenSource;\n\n constructor({ client }: { client: StreamChat<StreamChatGenerics> }) {\n this.client = client;\n this.state = ConnectionState.Init;\n this.consecutiveFailures = 0;\n\n addConnectionEventListeners(this._onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'WSConnectionFallback:' + msg, { tags: ['connection_fallback', 'connection'], ...extra });\n }\n\n _setState(state: ConnectionState) {\n this._log(`_setState() - ${state}`);\n\n // transition from connecting => connected\n if (this.state === ConnectionState.Connecting && state === ConnectionState.Connected) {\n this.client.dispatchEvent({ type: 'connection.changed', online: true });\n }\n\n if (state === ConnectionState.Closed || state === ConnectionState.Disconnected) {\n this.client.dispatchEvent({ type: 'connection.changed', online: false });\n }\n\n this.state = state;\n }\n\n /** @private */\n _onlineStatusChanged = (event: { type: string }) => {\n this._log(`_onlineStatusChanged() - ${event.type}`);\n\n if (event.type === 'offline') {\n this._setState(ConnectionState.Closed);\n this.cancelToken?.cancel('disconnect() is called');\n this.cancelToken = undefined;\n return;\n }\n\n if (event.type === 'online' && this.state === ConnectionState.Closed) {\n this.connect(true);\n }\n };\n\n /** @private */\n _req = async <T = UR>(params: UR, config: AxiosRequestConfig, retry: boolean): Promise<T> => {\n if (!this.cancelToken && !params.close) {\n this.cancelToken = axios.CancelToken.source();\n }\n\n try {\n const res = await this.client.doAxiosRequest<T>(\n 'get',\n (this.client.baseURL as string).replace(':3030', ':8900') + '/longpoll', // replace port if present for testing with local API\n undefined,\n {\n config: { ...config, cancelToken: this.cancelToken?.token },\n params,\n },\n );\n\n this.consecutiveFailures = 0; // always reset in case of no error\n return res;\n } catch (err) {\n this.consecutiveFailures += 1;\n\n if (retry && isErrorRetryable(err)) {\n this._log(`_req() - Retryable error, retrying request`);\n await sleep(retryInterval(this.consecutiveFailures));\n return this._req<T>(params, config, retry);\n }\n\n throw err;\n }\n };\n\n /** @private */\n _poll = async () => {\n while (this.state === ConnectionState.Connected) {\n try {\n const data = await this._req<{\n events: Event<StreamChatGenerics>[];\n }>({}, { timeout: 30000 }, true); // 30s => API responds in 20s if there is no event\n\n if (data.events?.length) {\n for (let i = 0; i < data.events.length; i++) {\n this.client.dispatchEvent(data.events[i]);\n }\n }\n } catch (err) {\n if (axios.isCancel(err)) {\n this._log(`_poll() - axios canceled request`);\n return;\n }\n\n /** client.doAxiosRequest will take care of TOKEN_EXPIRED error */\n\n if (isConnectionIDError(err)) {\n this._log(`_poll() - ConnectionID error, connecting without ID...`);\n this._setState(ConnectionState.Disconnected);\n this.connect(true);\n return;\n }\n\n if (isAPIError(err) && !isErrorRetryable(err)) {\n this._setState(ConnectionState.Closed);\n return;\n }\n\n await sleep(retryInterval(this.consecutiveFailures));\n }\n }\n };\n\n /**\n * connect try to open a longpoll request\n * @param reconnect should be false for first call and true for subsequent calls to keep the connection alive and call recoverState\n */\n connect = async (reconnect = false) => {\n if (this.state === ConnectionState.Connecting) {\n this._log('connect() - connecting already in progress', { reconnect }, 'warn');\n return;\n }\n if (this.state === ConnectionState.Connected) {\n this._log('connect() - already connected and polling', { reconnect }, 'warn');\n return;\n }\n\n this._setState(ConnectionState.Connecting);\n this.connectionID = undefined; // connect should be sent with empty connection_id so API creates one\n try {\n const { event } = await this._req<{ event: ConnectionOpen<StreamChatGenerics> }>(\n { json: this.client._buildWSPayload() },\n { timeout: 8000 }, // 8s\n reconnect,\n );\n\n this._setState(ConnectionState.Connected);\n this.connectionID = event.connection_id;\n // @ts-expect-error\n this.client.dispatchEvent(event);\n this._poll();\n if (reconnect) {\n this.client.recoverState();\n }\n return event;\n } catch (err) {\n this._setState(ConnectionState.Closed);\n throw err;\n }\n };\n\n /**\n * isHealthy checks if there is a connectionID and connection is in Connected state\n */\n isHealthy = () => {\n return !!this.connectionID && this.state === ConnectionState.Connected;\n };\n\n disconnect = async (timeout = 2000) => {\n removeConnectionEventListeners(this._onlineStatusChanged);\n\n this._setState(ConnectionState.Disconnected);\n this.cancelToken?.cancel('disconnect() is called');\n this.cancelToken = undefined;\n\n const connection_id = this.connectionID;\n this.connectionID = undefined;\n\n try {\n await this._req({ close: true, connection_id }, { timeout }, false);\n this._log(`disconnect() - Closed connectionID`);\n } catch (err) {\n this._log(`disconnect() - Failed`, { err }, 'error');\n }\n };\n}\n","import { Secret } from 'jsonwebtoken';\nimport { UserFromToken, JWTServerToken, JWTUserToken } from './signing';\nimport { isFunction } from './utils';\nimport { TokenOrProvider, ExtendableGenerics, DefaultGenerics, UserResponse } from './types';\n\n/**\n * TokenManager\n *\n * Handles all the operations around user token.\n */\nexport class TokenManager<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n loadTokenPromise: Promise<string> | null;\n type: 'static' | 'provider';\n secret?: Secret;\n token?: string;\n tokenProvider?: TokenOrProvider;\n user?: UserResponse<StreamChatGenerics>;\n /**\n * Constructor\n *\n * @param {Secret} secret\n */\n constructor(secret?: Secret) {\n this.loadTokenPromise = null;\n if (secret) {\n this.secret = secret;\n }\n\n this.type = 'static';\n\n if (this.secret) {\n this.token = JWTServerToken(this.secret);\n }\n }\n\n /**\n * Set the static string token or token provider.\n * Token provider should return a token string or a promise which resolves to string token.\n *\n * @param {TokenOrProvider} tokenOrProvider\n * @param {UserResponse<StreamChatGenerics>} user\n */\n setTokenOrProvider = async (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {\n this.validateToken(tokenOrProvider, user);\n this.user = user;\n\n if (isFunction(tokenOrProvider)) {\n this.tokenProvider = tokenOrProvider;\n this.type = 'provider';\n }\n\n if (typeof tokenOrProvider === 'string') {\n this.token = tokenOrProvider;\n this.type = 'static';\n }\n\n if (!tokenOrProvider && this.user && this.secret) {\n this.token = JWTUserToken(this.secret, user.id, {}, {});\n this.type = 'static';\n }\n\n await this.loadToken();\n };\n\n /**\n * Resets the token manager.\n * Useful for client disconnection or switching user.\n */\n reset = () => {\n this.token = undefined;\n this.tokenProvider = undefined;\n this.type = 'static';\n this.user = undefined;\n this.loadTokenPromise = null;\n };\n\n // Validates the user token.\n validateToken = (tokenOrProvider: TokenOrProvider, user: UserResponse<StreamChatGenerics>) => {\n // allow empty token for anon user\n if (user && user.anon && !tokenOrProvider) return;\n\n // Don't allow empty token for non-server side client.\n if (!this.secret && !tokenOrProvider) {\n throw new Error('User token can not be empty');\n }\n\n if (tokenOrProvider && typeof tokenOrProvider !== 'string' && !isFunction(tokenOrProvider)) {\n throw new Error('user token should either be a string or a function');\n }\n\n if (typeof tokenOrProvider === 'string') {\n // Allow empty token for anonymous users\n if (user.anon && tokenOrProvider === '') return;\n\n const tokenUserId = UserFromToken(tokenOrProvider);\n if (tokenOrProvider != null && (tokenUserId == null || tokenUserId === '' || tokenUserId !== user.id)) {\n throw new Error('userToken does not have a user_id or is not matching with user.id');\n }\n }\n };\n\n // Resolves when token is ready. This function is simply to check if loadToken is in progress, in which\n // case a function should wait.\n tokenReady = () => this.loadTokenPromise;\n\n // Fetches a token from tokenProvider function and sets in tokenManager.\n // In case of static token, it will simply resolve to static token.\n loadToken = () => {\n // eslint-disable-next-line no-async-promise-executor\n this.loadTokenPromise = new Promise(async (resolve, reject) => {\n if (this.type === 'static') {\n return resolve(this.token as string);\n }\n\n if (this.tokenProvider && typeof this.tokenProvider !== 'string') {\n try {\n this.token = await this.tokenProvider();\n } catch (e) {\n return reject(new Error(`Call to tokenProvider failed with message: ${e}`));\n }\n resolve(this.token);\n }\n });\n\n return this.loadTokenPromise;\n };\n\n // Returns a current token\n getToken = () => {\n if (this.token) {\n return this.token;\n }\n\n if (this.user && this.user.anon && !this.token) {\n return this.token;\n }\n\n if (this.secret) {\n return JWTServerToken(this.secret);\n }\n\n throw new Error(\n `Both secret and user tokens are not set. Either client.connectUser wasn't called or client.disconnect was called`,\n );\n };\n\n isStatic = () => this.type === 'static';\n}\n","import { AxiosResponse } from 'axios';\nimport { APIErrorResponse } from './types';\n\nexport const APIErrorCodes: Record<string, { name: string; retryable: boolean }> = {\n '-1': { name: 'InternalSystemError', retryable: true },\n '2': { name: 'AccessKeyError', retryable: false },\n '3': { name: 'AuthenticationFailedError', retryable: true },\n '4': { name: 'InputError', retryable: false },\n '6': { name: 'DuplicateUsernameError', retryable: false },\n '9': { name: 'RateLimitError', retryable: true },\n '16': { name: 'DoesNotExistError', retryable: false },\n '17': { name: 'NotAllowedError', retryable: false },\n '18': { name: 'EventNotSupportedError', retryable: false },\n '19': { name: 'ChannelFeatureNotSupportedError', retryable: false },\n '20': { name: 'MessageTooLongError', retryable: false },\n '21': { name: 'MultipleNestingLevelError', retryable: false },\n '22': { name: 'PayloadTooBigError', retryable: false },\n '23': { name: 'RequestTimeoutError', retryable: true },\n '24': { name: 'MaxHeaderSizeExceededError', retryable: false },\n '40': { name: 'AuthErrorTokenExpired', retryable: false },\n '41': { name: 'AuthErrorTokenNotValidYet', retryable: false },\n '42': { name: 'AuthErrorTokenUsedBeforeIssuedAt', retryable: false },\n '43': { name: 'AuthErrorTokenSignatureInvalid', retryable: false },\n '44': { name: 'CustomCommandEndpointMissingError', retryable: false },\n '45': { name: 'CustomCommandEndpointCallError', retryable: true },\n '46': { name: 'ConnectionIDNotFoundError', retryable: false },\n '60': { name: 'CoolDownError', retryable: true },\n '69': { name: 'ErrWrongRegion', retryable: false },\n '70': { name: 'ErrQueryChannelPermissions', retryable: false },\n '71': { name: 'ErrTooManyConnections', retryable: true },\n '99': { name: 'AppSuspendedError', retryable: false },\n};\n\ntype APIError = Error & { code: number; isWSFailure?: boolean };\n\nexport function isAPIError(error: Error): error is APIError {\n return (error as APIError).code !== undefined;\n}\n\nexport function isErrorRetryable(error: APIError) {\n if (!error.code) return false;\n const err = APIErrorCodes[`${error.code}`];\n if (!err) return false;\n return err.retryable;\n}\n\nexport function isConnectionIDError(error: APIError) {\n return error.code === 46; // ConnectionIDNotFoundError\n}\n\nexport function isWSFailure(err: APIError): boolean {\n if (typeof err.isWSFailure === 'boolean') {\n return err.isWSFailure;\n }\n\n try {\n return JSON.parse(err.message).isWSFailure;\n } catch (_) {\n return false;\n }\n}\n\nexport function isErrorResponse(res: AxiosResponse<unknown>): res is AxiosResponse<APIErrorResponse> {\n return !res.status || res.status < 200 || 300 <= res.status;\n}\n","import { StreamChat } from './client';\nimport {\n DefaultGenerics,\n ExtendableGenerics,\n QuerySegmentTargetsFilter,\n SegmentData,\n SegmentResponse,\n SortParam,\n} from './types';\n\ntype SegmentType = 'user' | 'channel';\n\ntype SegmentUpdatableFields = {\n description?: string;\n filter?: {};\n name?: string;\n};\n\nexport class Segment<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n type: SegmentType;\n id: string | null;\n client: StreamChat<StreamChatGenerics>;\n data?: SegmentData | SegmentResponse;\n\n constructor(client: StreamChat<StreamChatGenerics>, type: SegmentType, id: string | null, data?: SegmentData) {\n this.client = client;\n this.type = type;\n this.id = id;\n this.data = data;\n }\n\n async create() {\n const body = {\n name: this.data?.name,\n filter: this.data?.filter,\n description: this.data?.description,\n all_sender_channels: this.data?.all_sender_channels,\n all_users: this.data?.all_users,\n };\n\n return this.client.createSegment(this.type, this.id, body);\n }\n\n verifySegmentId() {\n if (!this.id) {\n throw new Error(\n 'Segment id is missing. Either create the segment using segment.create() or set the id during instantiation - const segment = client.segment(id)',\n );\n }\n }\n\n async get() {\n this.verifySegmentId();\n return this.client.getSegment(this.id as string);\n }\n\n async update(data: Partial<SegmentUpdatableFields>) {\n this.verifySegmentId();\n\n return this.client.updateSegment(this.id as string, data);\n }\n\n async addTargets(targets: string[]) {\n this.verifySegmentId();\n return this.client.addSegmentTargets(this.id as string, targets);\n }\n\n async removeTargets(targets: string[]) {\n this.verifySegmentId();\n return this.client.removeSegmentTargets(this.id as string, targets);\n }\n\n async delete() {\n this.verifySegmentId();\n return this.client.deleteSegment(this.id as string);\n }\n\n async targetExists(targetId: string) {\n this.verifySegmentId();\n return this.client.segmentTargetExists(this.id as string, targetId);\n }\n\n async queryTargets(filter: QuerySegmentTargetsFilter | null = {}, sort: SortParam[] | null | [] = [], options = {}) {\n this.verifySegmentId();\n\n return this.client.querySegmentTargets(this.id as string, filter, sort, options);\n }\n}\n","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import _typeof from \"@babel/runtime/helpers/typeof\";\nimport assertThisInitialized from \"./assertThisInitialized.js\";\nexport default function _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError(\"Derived constructors may only return object or undefined\");\n }\n\n return assertThisInitialized(self);\n}","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","export default function _isNativeReflectConstruct() {\n if (typeof Reflect === \"undefined\" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === \"function\") return true;\n\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeReflectConstruct from \"./isNativeReflectConstruct.js\";\nexport default function _construct(Parent, args, Class) {\n if (isNativeReflectConstruct()) {\n _construct = Reflect.construct;\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n }\n\n return _construct.apply(null, arguments);\n}","import getPrototypeOf from \"./getPrototypeOf.js\";\nimport setPrototypeOf from \"./setPrototypeOf.js\";\nimport isNativeFunction from \"./isNativeFunction.js\";\nimport construct from \"./construct.js\";\nexport default function _wrapNativeSuper(Class) {\n var _cache = typeof Map === \"function\" ? new Map() : undefined;\n\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !isNativeFunction(Class)) return Class;\n\n if (typeof Class !== \"function\") {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n if (typeof _cache !== \"undefined\") {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return construct(Class, arguments, getPrototypeOf(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return setPrototypeOf(Wrapper, Class);\n };\n\n return _wrapNativeSuper(Class);\n}","export default function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf(\"[native code]\") !== -1;\n}","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { StableWSConnection } from './connection';\nimport { EVENT_MAP } from './events';\nimport { Role } from './permissions';\n\n/**\n * Utility Types\n */\n\nexport type ArrayOneOrMore<T> = {\n 0: T;\n} & Array<T>;\n\nexport type ArrayTwoOrMore<T> = {\n 0: T;\n 1: T;\n} & Array<T>;\n\nexport type KnownKeys<T> = {\n [K in keyof T]: string extends K ? never : number extends K ? never : K;\n} extends { [_ in keyof T]: infer U }\n ? U\n : never;\n\nexport type RequireAtLeastOne<T> = {\n [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;\n}[keyof T];\n\nexport type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &\n {\n [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>;\n }[Keys];\n\n/* Unknown Record */\nexport type UR = Record<string, unknown>;\nexport type UnknownType = UR; //alias to avoid breaking change\n\nexport type DefaultGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: LiteralStringForUnion;\n eventType: UR;\n memberType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type ExtendableGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: string;\n eventType: UR;\n memberType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type Unpacked<T> = T extends (infer U)[]\n ? U // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : T extends (...args: any[]) => infer U\n ? U\n : T extends Promise<infer U>\n ? U\n : T;\n\n/**\n * Response Types\n */\n\nexport type APIResponse = {\n duration: string;\n};\n\nexport type AppSettingsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n app?: {\n // TODO\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n call_types: any;\n channel_configs: Record<\n string,\n {\n reminders: boolean;\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n commands?: CommandVariants<StreamChatGenerics>[];\n connect_events?: boolean;\n created_at?: string;\n custom_events?: boolean;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n replies?: boolean;\n search?: boolean;\n typing_events?: boolean;\n updated_at?: string;\n uploads?: boolean;\n url_enrichment?: boolean;\n }\n >;\n reminders_interval: number;\n agora_options?: AgoraOptions | null;\n async_moderation_config?: AsyncModerationOptions;\n async_url_enrich_enabled?: boolean;\n auto_translation_enabled?: boolean;\n before_message_send_hook_url?: string;\n campaign_enabled?: boolean;\n cdn_expiration_seconds?: number;\n custom_action_handler_url?: string;\n datadog_info?: {\n api_key: string;\n site: string;\n enabled?: boolean;\n };\n disable_auth_checks?: boolean;\n disable_permissions_checks?: boolean;\n enforce_unique_usernames?: 'no' | 'app' | 'team';\n file_upload_config?: FileUploadConfig;\n geofences?: Array<{\n country_codes: Array<string>;\n description: string;\n name: string;\n type: string;\n }>;\n grants?: Record<string, string[]>;\n hms_options?: HMSOptions | null;\n image_moderation_enabled?: boolean;\n image_upload_config?: FileUploadConfig;\n multi_tenant_enabled?: boolean;\n name?: string;\n organization?: string;\n permission_version?: string;\n policies?: Record<string, Policy[]>;\n poll_enabled?: boolean;\n push_notifications?: {\n offline_only: boolean;\n version: string;\n apn?: APNConfig;\n firebase?: FirebaseConfig;\n huawei?: HuaweiConfig;\n providers?: PushProviderConfig[];\n xiaomi?: XiaomiConfig;\n };\n revoke_tokens_issued_before?: string | null;\n search_backend?: 'disabled' | 'elasticsearch' | 'postgres';\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n suspended?: boolean;\n suspended_explanation?: string;\n user_search_disallowed_roles?: string[] | null;\n video_provider?: string;\n webhook_events?: Array<string>;\n webhook_url?: string;\n };\n};\n\nexport type ModerationResult = {\n action: string;\n created_at: string;\n message_id: string;\n updated_at: string;\n user_bad_karma: boolean;\n user_karma: number;\n blocked_word?: string;\n blocklist_name?: string;\n moderated_by?: string;\n};\n\nexport type AutomodDetails = {\n action?: string;\n image_labels?: Array<string>;\n original_message_type?: string;\n result?: ModerationResult;\n};\n\nexport type FlagDetails = {\n automod?: AutomodDetails;\n};\n\nexport type Flag<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n created_by_automod: boolean;\n updated_at: string;\n details?: FlagDetails;\n target_message?: MessageResponse<StreamChatGenerics>;\n target_user?: UserResponse<StreamChatGenerics>;\n user?: UserResponse<StreamChatGenerics>;\n};\n\nexport type FlagsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flags?: Array<Flag<StreamChatGenerics>>;\n};\n\nexport type MessageFlagsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flags?: Array<{\n message: MessageResponse<StreamChatGenerics>;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n created_at?: string;\n created_by_automod?: boolean;\n moderation_result?: ModerationResult;\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n }>;\n};\n\nexport type FlagReport<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n flags_count: number;\n id: string;\n message: MessageResponse<StreamChatGenerics>;\n user: UserResponse<StreamChatGenerics>;\n created_at?: string;\n details?: FlagDetails;\n first_reporter?: UserResponse<StreamChatGenerics>;\n review_result?: string;\n reviewed_at?: string;\n reviewed_by?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n};\n\nexport type FlagReportsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag_reports: Array<FlagReport<StreamChatGenerics>>;\n};\n\nexport type ReviewFlagReportResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag_report: FlagReport<StreamChatGenerics>;\n};\n\nexport type BannedUsersResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n bans?: Array<{\n user: UserResponse<StreamChatGenerics>;\n banned_by?: UserResponse<StreamChatGenerics>;\n channel?: ChannelResponse<StreamChatGenerics>;\n expires?: string;\n ip_ban?: boolean;\n reason?: string;\n timeout?: number;\n }>;\n};\n\nexport type BlockListResponse = BlockList & {\n created_at?: string;\n type?: string;\n updated_at?: string;\n};\n\nexport type ChannelResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['channelType'] & {\n cid: string;\n disabled: boolean;\n frozen: boolean;\n id: string;\n type: string;\n auto_translation_enabled?: boolean;\n auto_translation_language?: TranslationLanguages | '';\n config?: ChannelConfigWithInfo<StreamChatGenerics>;\n cooldown?: number;\n created_at?: string;\n created_by?: UserResponse<StreamChatGenerics> | null;\n created_by_id?: string;\n deleted_at?: string;\n hidden?: boolean;\n invites?: string[];\n joined?: boolean;\n last_message_at?: string;\n member_count?: number;\n members?: ChannelMemberResponse<StreamChatGenerics>[];\n muted?: boolean;\n name?: string;\n own_capabilities?: string[];\n team?: string;\n truncated_at?: string;\n truncated_by?: UserResponse<StreamChatGenerics>;\n truncated_by_id?: string;\n updated_at?: string;\n};\n\nexport type QueryReactionsOptions = Pager;\n\nexport type QueryReactionsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n reactions: ReactionResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type QueryChannelsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channels: Omit<ChannelAPIResponse<StreamChatGenerics>, keyof APIResponse>[];\n};\n\nexport type QueryChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n ChannelAPIResponse<StreamChatGenerics>;\n\nexport type ChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n messages: MessageResponse<StreamChatGenerics>[];\n pinned_messages: MessageResponse<StreamChatGenerics>[];\n hidden?: boolean;\n membership?: ChannelMemberResponse<StreamChatGenerics> | null;\n pending_messages?: PendingMessageResponse<StreamChatGenerics>[];\n read?: ReadResponse<StreamChatGenerics>[];\n threads?: ThreadResponse[];\n watcher_count?: number;\n watchers?: UserResponse<StreamChatGenerics>[];\n};\n\nexport type ChannelUpdateOptions = {\n hide_history?: boolean;\n skip_push?: boolean;\n};\n\nexport type ChannelMemberAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n members: ChannelMemberResponse<StreamChatGenerics>[];\n};\n\nexport type ChannelMemberUpdates<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & {\n archived?: boolean;\n channel_role?: Role;\n pinned?: boolean;\n};\n\nexport type ChannelMemberResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & {\n archived_at?: string;\n ban_expires?: string;\n banned?: boolean;\n channel_role?: Role;\n created_at?: string;\n invite_accepted_at?: string;\n invite_rejected_at?: string;\n invited?: boolean;\n is_moderator?: boolean;\n notifications_muted?: boolean;\n pinned_at?: string;\n role?: string;\n shadow_banned?: boolean;\n status?: InviteStatus;\n updated_at?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PartialUpdateMemberAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel_member: ChannelMemberResponse<StreamChatGenerics>;\n};\n\nexport type CheckPushResponse = APIResponse & {\n device_errors?: {\n [deviceID: string]: {\n error_message?: string;\n provider?: PushProvider;\n provider_name?: string;\n };\n };\n general_errors?: string[];\n rendered_apn_template?: string;\n rendered_firebase_template?: string;\n rendered_message?: {};\n skip_devices?: boolean;\n};\n\nexport type CheckSQSResponse = APIResponse & {\n status: string;\n data?: {};\n error?: string;\n};\n\nexport type CheckSNSResponse = APIResponse & {\n status: string;\n data?: {};\n error?: string;\n};\n\nexport type CommandResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Partial<CreatedAtUpdatedAt> & {\n args?: string;\n description?: string;\n name?: CommandVariants<StreamChatGenerics>;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type ConnectAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Promise<void | ConnectionOpen<StreamChatGenerics>>;\n\nexport type CreateChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id'> & {\n created_at: string;\n updated_at: string;\n grants?: Record<string, string[]>;\n };\n\nexport type CreateCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n command: CreateCommandOptions<StreamChatGenerics> & CreatedAtUpdatedAt;\n};\n\nexport type DeleteChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n};\n\nexport type DeleteCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n name?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type EventAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n event: Event<StreamChatGenerics>;\n};\n\nexport type ExportChannelResponse = {\n task_id: string;\n};\n\nexport type ExportUsersResponse = {\n task_id: string;\n};\n\nexport type ExportChannelStatusResponse = {\n created_at?: string;\n error?: {};\n result?: {};\n updated_at?: string;\n};\n\nexport type FlagMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag: {\n created_at: string;\n created_by_automod: boolean;\n target_message_id: string;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n channel_cid?: string;\n details?: Object; // Any JSON\n message_user_id?: string;\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: string;\n };\n review_queue_item_id?: string;\n};\n\nexport type FlagUserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n flag: {\n created_at: string;\n created_by_automod: boolean;\n target_user: UserResponse<StreamChatGenerics>;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n approved_at?: string;\n details?: Object; // Any JSON\n rejected_at?: string;\n reviewed_at?: string;\n reviewed_by?: string;\n };\n review_queue_item_id?: string;\n};\n\nexport type FormatMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'created_at' | 'pinned_at' | 'updated_at' | 'deleted_at' | 'status'\n> &\n StreamChatGenerics['messageType'] & {\n created_at: Date;\n deleted_at: Date | null;\n pinned_at: Date | null;\n status: string;\n updated_at: Date;\n };\n\nexport type GetChannelTypeResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id' | 'commands'> & {\n created_at: string;\n updated_at: string;\n commands?: CommandResponse<StreamChatGenerics>[];\n grants?: Record<string, string[]>;\n };\n\nexport type GetCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n CreateCommandOptions<StreamChatGenerics> &\n CreatedAtUpdatedAt;\n\nexport type GetMessageAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = SendMessageAPIResponse<StreamChatGenerics>;\n\nexport interface ThreadResponse<SCG extends ExtendableGenerics = DefaultGenerics> {\n // FIXME: according to OpenAPI, `channel` could be undefined but since cid is provided I'll asume that it's wrong\n channel: ChannelResponse<SCG>;\n channel_cid: string;\n created_at: string;\n created_by_user_id: string;\n latest_replies: Array<MessageResponse<SCG>>;\n parent_message: MessageResponse<SCG>;\n parent_message_id: string;\n title: string;\n updated_at: string;\n created_by?: UserResponse<SCG>;\n deleted_at?: string;\n last_message_at?: string;\n participant_count?: number;\n read?: Array<ReadResponse<SCG>>;\n reply_count?: number;\n thread_participants?: Array<{\n channel_cid: string;\n created_at: string;\n last_read_at: string;\n last_thread_message_at?: string;\n left_thread_at?: string;\n thread_id?: string;\n user?: UserResponse<SCG>;\n user_id?: string;\n }>;\n}\n\n// TODO: Figure out a way to strongly type set and unset.\nexport type PartialThreadUpdate = {\n set?: Partial<Record<string, unknown>>;\n unset?: Array<string>;\n};\n\nexport type QueryThreadsOptions = {\n limit?: number;\n member_limit?: number;\n next?: string;\n participant_limit?: number;\n reply_limit?: number;\n watch?: boolean;\n};\n\nexport type QueryThreadsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n threads: ThreadResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type GetThreadOptions = {\n member_limit?: number;\n participant_limit?: number;\n reply_limit?: number;\n watch?: boolean;\n};\n\nexport type GetThreadAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n thread: ThreadResponse<StreamChatGenerics>;\n};\n\nexport type GetMultipleMessagesAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n};\n\nexport type GetRateLimitsResponse = APIResponse & {\n android?: RateLimitsMap;\n ios?: RateLimitsMap;\n server_side?: RateLimitsMap;\n web?: RateLimitsMap;\n};\n\nexport type GetReactionsAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n reactions: ReactionResponse<StreamChatGenerics>[];\n};\n\nexport type GetRepliesAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n};\n\nexport type GetUnreadCountAPIResponse = APIResponse & {\n channel_type: {\n channel_count: number;\n channel_type: string;\n unread_count: number;\n }[];\n channels: {\n channel_id: string;\n last_read: string;\n unread_count: number;\n }[];\n threads: {\n last_read: string;\n last_read_message_id: string;\n parent_message_id: string;\n unread_count: number;\n }[];\n total_unread_count: number;\n total_unread_threads_count: number;\n};\n\nexport type GetUnreadCountBatchAPIResponse = APIResponse & {\n counts_by_user: { [userId: string]: GetUnreadCountAPIResponse };\n};\n\nexport type ListChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel_types: Record<\n string,\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id' | 'commands'> & {\n commands: CommandResponse<StreamChatGenerics>[];\n created_at: string;\n updated_at: string;\n grants?: Record<string, string[]>;\n }\n >;\n};\n\nexport type ListChannelTypesAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ListChannelResponse<StreamChatGenerics>;\n\nexport type ListCommandsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n commands: Array<CreateCommandOptions<StreamChatGenerics> & Partial<CreatedAtUpdatedAt>>;\n};\n\nexport type MuteChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel_mute: ChannelMute<StreamChatGenerics>;\n own_user: OwnUserResponse<StreamChatGenerics>;\n channel_mutes?: ChannelMute<StreamChatGenerics>[];\n mute?: MuteResponse<StreamChatGenerics>;\n};\n\nexport type MessageResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MessageResponseBase<StreamChatGenerics> & {\n quoted_message?: MessageResponseBase<StreamChatGenerics>;\n};\n\nexport type MessageResponseBase<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MessageBase<StreamChatGenerics> & {\n type: MessageLabel;\n args?: string;\n before_message_send_failed?: boolean;\n channel?: ChannelResponse<StreamChatGenerics>;\n cid?: string;\n command?: string;\n command_info?: { name?: string };\n created_at?: string;\n deleted_at?: string;\n deleted_reply_count?: number;\n i18n?: RequireAtLeastOne<Record<`${TranslationLanguages}_text`, string>> & {\n language: TranslationLanguages;\n };\n latest_reactions?: ReactionResponse<StreamChatGenerics>[];\n mentioned_users?: UserResponse<StreamChatGenerics>[];\n message_text_updated_at?: string;\n moderation?: ModerationResponse; // present only with Moderation v2\n moderation_details?: ModerationDetailsResponse; // present only with Moderation v1\n own_reactions?: ReactionResponse<StreamChatGenerics>[] | null;\n pin_expires?: string | null;\n pinned_at?: string | null;\n pinned_by?: UserResponse<StreamChatGenerics> | null;\n poll?: PollResponse<StreamChatGenerics>;\n reaction_counts?: { [key: string]: number } | null;\n reaction_groups?: { [key: string]: ReactionGroupResponse } | null;\n reaction_scores?: { [key: string]: number } | null;\n reply_count?: number;\n shadowed?: boolean;\n status?: string;\n thread_participants?: UserResponse<StreamChatGenerics>[];\n updated_at?: string;\n};\n\nexport type ReactionGroupResponse = {\n count: number;\n sum_scores: number;\n first_reaction_at?: string;\n last_reaction_at?: string;\n};\n\nexport type ModerationDetailsResponse = {\n action: 'MESSAGE_RESPONSE_ACTION_BOUNCE' | (string & {});\n error_msg: string;\n harms: ModerationHarmResponse[];\n original_text: string;\n};\n\nexport type ModerationHarmResponse = {\n name: string;\n phrase_list_ids: number[];\n};\n\nexport type ModerationAction = 'bounce' | 'flag' | 'remove' | 'shadow';\n\nexport type ModerationResponse = {\n action: ModerationAction;\n original_text: string;\n};\n\nexport type MuteResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n created_at?: string;\n expires?: string;\n target?: UserResponse<StreamChatGenerics>;\n updated_at?: string;\n};\n\nexport type MuteUserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n mute?: MuteResponse<StreamChatGenerics>;\n mutes?: Array<Mute<StreamChatGenerics>>;\n own_user?: OwnUserResponse<StreamChatGenerics>;\n};\n\nexport type BlockUserAPIResponse = APIResponse & {\n blocked_at: string;\n blocked_by_user_id: string;\n blocked_user_id: string;\n};\n\nexport type GetBlockedUsersAPIResponse = APIResponse & {\n blocks: BlockedUserDetails[];\n};\nexport type BlockedUserDetails = APIResponse & {\n blocked_user: UserResponse;\n blocked_user_id: string;\n created_at: string;\n user: UserResponse;\n user_id: string;\n};\n\nexport type OwnUserBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel_mutes: ChannelMute<StreamChatGenerics>[];\n devices: Device<StreamChatGenerics>[];\n mutes: Mute<StreamChatGenerics>[];\n total_unread_count: number;\n unread_channels: number;\n unread_count: number;\n unread_threads: number;\n invisible?: boolean;\n privacy_settings?: PrivacySettings;\n roles?: string[];\n};\n\nexport type OwnUserResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = UserResponse<StreamChatGenerics> & OwnUserBase<StreamChatGenerics>;\n\nexport type PartialUpdateChannelAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n};\n\nexport type PermissionAPIResponse = APIResponse & {\n permission?: PermissionAPIObject;\n};\n\nexport type PermissionsAPIResponse = APIResponse & {\n permissions?: PermissionAPIObject[];\n};\n\nexport type ReactionAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n reaction: ReactionResponse<StreamChatGenerics>;\n};\n\nexport type ReactionResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = Reaction<StreamChatGenerics> & {\n created_at: string;\n message_id: string;\n updated_at: string;\n};\n\nexport type ReadResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n last_read: string;\n user: UserResponse<StreamChatGenerics>;\n last_read_message_id?: string;\n unread_messages?: number;\n};\n\nexport type SearchAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n results: {\n message: MessageResponse<StreamChatGenerics>;\n }[];\n next?: string;\n previous?: string;\n results_warning?: SearchWarning | null;\n};\n\nexport type SearchWarning = {\n channel_search_cids: string[];\n channel_search_count: number;\n warning_code: number;\n warning_description: string;\n};\n\n// Thumb URL(thumb_url) is added considering video attachments as the backend will return the thumbnail in the response.\nexport type SendFileAPIResponse = APIResponse & { file: string; thumb_url?: string };\n\nexport type SendMessageAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n pending_message_metadata?: Record<string, string> | null;\n};\n\nexport type SyncResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n events: Event<StreamChatGenerics>[];\n inaccessible_cids?: string[];\n};\n\nexport type TruncateChannelAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n message?: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UpdateChannelAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<StreamChatGenerics>;\n members: ChannelMemberResponse<StreamChatGenerics>[];\n message?: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UpdateChannelResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n Omit<CreateChannelOptions<StreamChatGenerics>, 'client_id' | 'connection_id'> & {\n created_at: string;\n updated_at: string;\n };\n\nexport type UpdateCommandResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n command: UpdateCommandOptions<StreamChatGenerics> &\n CreatedAtUpdatedAt & {\n name: CommandVariants<StreamChatGenerics>;\n };\n};\n\nexport type UpdateMessageAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<StreamChatGenerics>;\n};\n\nexport type UsersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n users: Array<UserResponse<StreamChatGenerics>>;\n};\n\nexport type UpdateUsersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n};\n\nexport type UserResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = User<StreamChatGenerics> & {\n banned?: boolean;\n blocked_user_ids?: string[];\n created_at?: string;\n deactivated_at?: string;\n deleted_at?: string;\n language?: TranslationLanguages | '';\n last_active?: string;\n online?: boolean;\n privacy_settings?: PrivacySettings;\n push_notifications?: PushNotificationSettings;\n revoke_tokens_issued_before?: string;\n shadow_banned?: boolean;\n updated_at?: string;\n};\n\nexport type PrivacySettings = {\n read_receipts?: {\n enabled?: boolean;\n };\n typing_indicators?: {\n enabled?: boolean;\n };\n};\n\nexport type PushNotificationSettings = {\n disabled?: boolean;\n disabled_until?: string | null;\n};\n\n/**\n * Option Types\n */\n\nexport type MessageFlagsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type FlagsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type FlagReportsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type ReviewFlagReportOptions = {\n review_details?: Object;\n user_id?: string;\n};\n\nexport type BannedUsersPaginationOptions = Omit<PaginationOptions, 'id_gt' | 'id_gte' | 'id_lt' | 'id_lte'> & {\n exclude_expired_bans?: boolean;\n};\n\nexport type BanUserOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = UnBanUserOptions & {\n banned_by?: UserResponse<StreamChatGenerics>;\n banned_by_id?: string;\n ip_ban?: boolean;\n reason?: string;\n timeout?: number;\n};\n\nexport type ChannelOptions = {\n limit?: number;\n member_limit?: number;\n message_limit?: number;\n offset?: number;\n presence?: boolean;\n state?: boolean;\n user_id?: string;\n watch?: boolean;\n};\n\nexport type ChannelQueryOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n data?: ChannelResponse<StreamChatGenerics>;\n hide_for_creator?: boolean;\n members?: PaginationOptions;\n messages?: MessagePaginationOptions;\n presence?: boolean;\n state?: boolean;\n watch?: boolean;\n watchers?: PaginationOptions;\n};\n\nexport type ChannelStateOptions = {\n offlineMode?: boolean;\n skipInitialization?: string[];\n};\n\nexport type CreateChannelOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist?: string;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n client_id?: string;\n commands?: CommandVariants<StreamChatGenerics>[];\n connect_events?: boolean;\n connection_id?: string;\n custom_events?: boolean;\n grants?: Record<string, string[]>;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n permissions?: PermissionObject[];\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n reminders?: boolean;\n replies?: boolean;\n search?: boolean;\n skip_last_msg_update_for_system_msgs?: boolean;\n typing_events?: boolean;\n uploads?: boolean;\n url_enrichment?: boolean;\n};\n\nexport type CreateCommandOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n description: string;\n name: CommandVariants<StreamChatGenerics>;\n args?: string;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type CustomPermissionOptions = {\n action: string;\n condition: object;\n id: string;\n name: string;\n description?: string;\n owner?: boolean;\n same_team?: boolean;\n};\n\nexport type DeactivateUsersOptions = {\n created_by_id?: string;\n mark_messages_deleted?: boolean;\n};\n\nexport type NewMemberPayload<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['memberType'] & Pick<ChannelMemberResponse<StreamChatGenerics>, 'user_id' | 'channel_role'>;\n\n// TODO: rename to UpdateChannelOptions in the next major update and use it in channel._update and/or channel.update\nexport type InviteOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n accept_invite?: boolean;\n add_members?: string[];\n add_moderators?: string[];\n client_id?: string;\n connection_id?: string;\n data?: Omit<ChannelResponse<StreamChatGenerics>, 'id' | 'cid'>;\n demote_moderators?: string[];\n invites?: string[];\n message?: MessageResponse<StreamChatGenerics>;\n reject_invite?: boolean;\n remove_members?: string[];\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\n/** @deprecated use MarkChannelsReadOptions instead */\nexport type MarkAllReadOptions<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = MarkChannelsReadOptions<StreamChatGenerics>;\n\nexport type MarkChannelsReadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n read_by_channel?: Record<string, string>;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MarkReadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n thread_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MarkUnreadOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n message_id?: string;\n thread_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type MuteUserOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n client_id?: string;\n connection_id?: string;\n id?: string;\n reason?: string;\n target_user_id?: string;\n timeout?: number;\n type?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PaginationOptions = {\n created_at_after?: string | Date;\n created_at_after_or_equal?: string | Date;\n created_at_before?: string | Date;\n created_at_before_or_equal?: string | Date;\n id_gt?: string;\n id_gte?: string;\n id_lt?: string;\n id_lte?: string;\n limit?: number;\n offset?: number; // should be avoided with channel.query()\n};\n\nexport type MessagePaginationOptions = PaginationOptions & {\n created_at_around?: string | Date;\n id_around?: string;\n};\n\nexport type PinnedMessagePaginationOptions = {\n id_around?: string;\n id_gt?: string;\n id_gte?: string;\n id_lt?: string;\n id_lte?: string;\n limit?: number;\n offset?: number;\n pinned_at_after?: string | Date;\n pinned_at_after_or_equal?: string | Date;\n pinned_at_around?: string | Date;\n pinned_at_before?: string | Date;\n pinned_at_before_or_equal?: string | Date;\n};\n\nexport type QueryMembersOptions = {\n // Pagination option: select members created after the date (RFC399)\n created_at_after?: string;\n // Pagination option: select members created after or equal the date (RFC399)\n created_at_after_or_equal?: string;\n // Pagination option: select members created before the date (RFC399)\n created_at_before?: string;\n // Pagination option: select members created before or equal the date (RFC399)\n created_at_before_or_equal?: string;\n // Number of members to return, default 100\n limit?: number;\n // Offset (max is 1000)\n offset?: number;\n // \tPagination option: excludes members with ID less or equal the value\n user_id_gt?: string;\n // Pagination option: excludes members with ID less than the value\n user_id_gte?: string;\n // Pagination option: excludes members with ID greater or equal the value\n user_id_lt?: string;\n // \tPagination option: excludes members with ID greater than the value\n user_id_lte?: string;\n};\n\nexport type ReactivateUserOptions = {\n created_by_id?: string;\n name?: string;\n restore_messages?: boolean;\n};\n\nexport type ReactivateUsersOptions = {\n created_by_id?: string;\n restore_messages?: boolean;\n};\n\nexport type SearchOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n limit?: number;\n next?: string;\n offset?: number;\n sort?: SearchMessageSort<StreamChatGenerics>;\n};\n\nexport type StreamChatOptions = AxiosRequestConfig & {\n /**\n * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.\n */\n allowServerSideConnect?: boolean;\n axiosRequestConfig?: AxiosRequestConfig;\n /**\n * Base url to use for API\n * such as https://chat-proxy-dublin.stream-io-api.com\n */\n baseURL?: string;\n browser?: boolean;\n device?: BaseDeviceFields;\n enableInsights?: boolean;\n /** experimental feature, please contact support if you want this feature enabled for you */\n enableWSFallback?: boolean;\n logger?: Logger;\n /**\n * When true, user will be persisted on client. Otherwise if `connectUser` call fails, then you need to\n * call `connectUser` again to retry.\n * This is mainly useful for chat application working in offline mode, where you will need client.user to\n * persist even if connectUser call fails.\n */\n persistUserOnConnectionFailure?: boolean;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n warmUp?: boolean;\n // Set the instance of StableWSConnection on chat client. Its purely for testing purpose and should\n // not be used in production apps.\n wsConnection?: StableWSConnection;\n};\n\nexport type SyncOptions = {\n /**\n * This will behave as queryChannels option.\n */\n watch?: boolean;\n /**\n * Return channels from request that user does not have access to in a separate\n * field in the response called 'inaccessible_cids' instead of\n * adding them as 'notification.removed_from_channel' events.\n */\n with_inaccessible_cids?: boolean;\n};\n\nexport type UnBanUserOptions = {\n client_id?: string;\n connection_id?: string;\n id?: string;\n shadow?: boolean;\n target_user_id?: string;\n type?: string;\n};\n\n// TODO: rename to UpdateChannelTypeOptions in the next major update\nexport type UpdateChannelOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n CreateChannelOptions<StreamChatGenerics>,\n 'name'\n> & {\n created_at?: string;\n updated_at?: string;\n};\n\nexport type UpdateCommandOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n description: string;\n args?: string;\n set?: CommandVariants<StreamChatGenerics>;\n};\n\nexport type UserOptions = {\n include_deactivated_users?: boolean;\n limit?: number;\n offset?: number;\n presence?: boolean;\n};\n\n/**\n * Event Types\n */\n\nexport type ConnectionChangeEvent = {\n type: EventTypes;\n online?: boolean;\n};\n\nexport type Event<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = StreamChatGenerics['eventType'] & {\n type: EventTypes;\n channel?: ChannelResponse<StreamChatGenerics>;\n channel_id?: string;\n channel_type?: string;\n cid?: string;\n clear_history?: boolean;\n connection_id?: string;\n // event creation timestamp, format Date ISO string\n created_at?: string;\n // id of the message that was marked as unread - all the following messages are considered unread. (notification.mark_unread)\n first_unread_message_id?: string;\n hard_delete?: boolean;\n // creation date of a message with last_read_message_id, formatted as Date ISO string\n last_read_at?: string;\n last_read_message_id?: string;\n mark_messages_deleted?: boolean;\n me?: OwnUserResponse<StreamChatGenerics>;\n member?: ChannelMemberResponse<StreamChatGenerics>;\n message?: MessageResponse<StreamChatGenerics>;\n mode?: string;\n online?: boolean;\n parent_id?: string;\n poll?: PollResponse<StreamChatGenerics>;\n poll_vote?: PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>;\n queriedChannels?: {\n channels: ChannelAPIResponse<StreamChatGenerics>[];\n isLatestMessageSet?: boolean;\n };\n reaction?: ReactionResponse<StreamChatGenerics>;\n received_at?: string | Date;\n team?: string;\n thread?: ThreadResponse<StreamChatGenerics>;\n // @deprecated number of all unread messages across all current user's unread channels, equals unread_count\n total_unread_count?: number;\n // number of all current user's channels with at least one unread message including the channel in this event\n unread_channels?: number;\n // number of all unread messages across all current user's unread channels\n unread_count?: number;\n // number of unread messages in the channel from this event (notification.mark_unread)\n unread_messages?: number;\n unread_thread_messages?: number;\n unread_threads?: number;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n watcher_count?: number;\n};\n\nexport type UserCustomEvent<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['eventType'] & {\n type: string;\n};\n\nexport type EventHandler<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = (\n event: Event<StreamChatGenerics>,\n) => void;\n\nexport type EventTypes = 'all' | keyof typeof EVENT_MAP;\n\n/**\n * Filter Types\n */\n\nexport type AscDesc = 1 | -1;\n\nexport type MessageFlagsFiltersOptions = {\n channel_cid?: string;\n is_reviewed?: boolean;\n team?: string;\n user_id?: string;\n};\n\nexport type MessageFlagsFilters = QueryFilters<\n {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['channel_cid']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['team']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageFlagsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageFlagsFiltersOptions['user_id']>;\n } & {\n [Key in keyof Omit<MessageFlagsFiltersOptions, 'channel_cid' | 'user_id' | 'is_reviewed'>]:\n | RequireOnlyOne<QueryFilter<MessageFlagsFiltersOptions[Key]>>\n | PrimitiveFilter<MessageFlagsFiltersOptions[Key]>;\n }\n>;\n\nexport type FlagsFiltersOptions = {\n channel_cid?: string;\n message_id?: string;\n message_user_id?: string;\n reporter_id?: string;\n team?: string;\n user_id?: string;\n};\n\nexport type FlagsFilters = QueryFilters<\n {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['user_id']>;\n } & {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['message_id']>;\n } & {\n message_user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['message_user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['message_user_id']>;\n } & {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['channel_cid']>;\n } & {\n reporter_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['reporter_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['reporter_id']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagsFiltersOptions['team']>;\n }\n>;\n\nexport type FlagReportsFiltersOptions = {\n channel_cid?: string;\n is_reviewed?: boolean;\n message_id?: string;\n message_user_id?: string;\n report_id?: string;\n review_result?: string;\n reviewed_by?: string;\n team?: string;\n user_id?: string;\n};\n\nexport type FlagReportsFilters = QueryFilters<\n {\n report_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['report_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['report_id']>;\n } & {\n review_result?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['review_result']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['review_result']>;\n } & {\n reviewed_by?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['reviewed_by']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['reviewed_by']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['user_id']>;\n } & {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['message_id']>;\n } & {\n message_user_id?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['message_user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['message_user_id']>;\n } & {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['channel_cid']>;\n } & {\n team?:\n | RequireOnlyOne<Pick<QueryFilter<FlagReportsFiltersOptions['team']>, '$eq' | '$in'>>\n | PrimitiveFilter<FlagReportsFiltersOptions['team']>;\n } & {\n [Key in keyof Omit<\n FlagReportsFiltersOptions,\n 'report_id' | 'user_id' | 'message_id' | 'review_result' | 'reviewed_by'\n >]: RequireOnlyOne<QueryFilter<FlagReportsFiltersOptions[Key]>> | PrimitiveFilter<FlagReportsFiltersOptions[Key]>;\n }\n>;\n\nexport type BannedUsersFilterOptions = {\n banned_by_id?: string;\n channel_cid?: string;\n created_at?: string;\n reason?: string;\n user_id?: string;\n};\n\nexport type BannedUsersFilters = QueryFilters<\n {\n channel_cid?:\n | RequireOnlyOne<Pick<QueryFilter<BannedUsersFilterOptions['channel_cid']>, '$eq' | '$in'>>\n | PrimitiveFilter<BannedUsersFilterOptions['channel_cid']>;\n } & {\n reason?:\n | RequireOnlyOne<\n {\n $autocomplete?: BannedUsersFilterOptions['reason'];\n } & QueryFilter<BannedUsersFilterOptions['reason']>\n >\n | PrimitiveFilter<BannedUsersFilterOptions['reason']>;\n } & {\n [Key in keyof Omit<BannedUsersFilterOptions, 'channel_cid' | 'reason'>]:\n | RequireOnlyOne<QueryFilter<BannedUsersFilterOptions[Key]>>\n | PrimitiveFilter<BannedUsersFilterOptions[Key]>;\n }\n>;\n\nexport type ReactionFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<ReactionResponse<StreamChatGenerics>['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReactionResponse<StreamChatGenerics>['user_id']>;\n } & {\n type?:\n | RequireOnlyOne<Pick<QueryFilter<ReactionResponse<StreamChatGenerics>['type']>, '$eq'>>\n | PrimitiveFilter<ReactionResponse<StreamChatGenerics>['type']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n }\n>;\n\nexport type ChannelFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['channelType']> & {\n members?:\n | RequireOnlyOne<Pick<QueryFilter<string>, '$in' | '$nin'>>\n | RequireOnlyOne<Pick<QueryFilter<string[]>, '$eq'>>\n | PrimitiveFilter<string[]>;\n } & {\n name?:\n | RequireOnlyOne<\n {\n $autocomplete?: ChannelResponse<StreamChatGenerics>['name'];\n } & QueryFilter<ChannelResponse<StreamChatGenerics>['name']>\n >\n | PrimitiveFilter<ChannelResponse<StreamChatGenerics>['name']>;\n } & {\n [Key in keyof Omit<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'name' | 'members'\n >]:\n | RequireOnlyOne<\n QueryFilter<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >\n >\n | PrimitiveFilter<\n ChannelResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: {};\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >;\n } & {\n archived?: boolean;\n pinned?: boolean;\n }\n>;\n\nexport type QueryPollsParams = {\n filter?: QueryPollsFilters;\n options?: QueryPollsOptions;\n sort?: PollSort;\n};\n\nexport type QueryPollsOptions = Pager;\n\nexport type VotesFiltersOptions = {\n is_answer?: boolean;\n option_id?: string;\n user_id?: string;\n};\n\nexport type QueryVotesOptions = Pager;\n\nexport type QueryPollsFilters = QueryFilters<\n {\n id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['user_id']>;\n } & {\n is_closed?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['is_closed']>, '$eq'>>\n | PrimitiveFilter<PollResponse['is_closed']>;\n } & {\n max_votes_allowed?:\n | RequireOnlyOne<\n Pick<QueryFilter<PollResponse['max_votes_allowed']>, '$eq' | '$ne' | '$gt' | '$lt' | '$gte' | '$lte'>\n >\n | PrimitiveFilter<PollResponse['max_votes_allowed']>;\n } & {\n allow_answers?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['allow_answers']>, '$eq'>>\n | PrimitiveFilter<PollResponse['allow_answers']>;\n } & {\n allow_user_suggested_options?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['allow_user_suggested_options']>, '$eq'>>\n | PrimitiveFilter<PollResponse['allow_user_suggested_options']>;\n } & {\n voting_visibility?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['voting_visibility']>, '$eq'>>\n | PrimitiveFilter<PollResponse['voting_visibility']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n } & {\n created_by_id?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['created_by_id']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['updated_at']>;\n } & {\n name?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['name']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['name']>;\n }\n>;\n\nexport type QueryVotesFilters = QueryFilters<\n {\n id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>;\n } & {\n option_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['option_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['option_id']>;\n } & {\n is_answer?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['is_answer']>, '$eq'>>\n | PrimitiveFilter<VotesFiltersOptions['is_answer']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<VotesFiltersOptions['user_id']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['created_at']>;\n } & {\n created_by_id?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<PollResponse['created_by_id']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<PollResponse['updated_at']>;\n }\n>;\n\nexport type ContainsOperator<CustomType = {}> = {\n [Key in keyof CustomType]?: CustomType[Key] extends (infer ContainType)[]\n ?\n | RequireOnlyOne<\n {\n $contains?: ContainType extends object\n ? PrimitiveFilter<RequireAtLeastOne<ContainType>>\n : PrimitiveFilter<ContainType>;\n } & QueryFilter<PrimitiveFilter<ContainType>[]>\n >\n | PrimitiveFilter<PrimitiveFilter<ContainType>[]>\n : RequireOnlyOne<QueryFilter<CustomType[Key]>> | PrimitiveFilter<CustomType[Key]>;\n};\n\nexport type MessageFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['messageType']> & {\n text?:\n | RequireOnlyOne<\n {\n $autocomplete?: MessageResponse<StreamChatGenerics>['text'];\n $q?: MessageResponse<StreamChatGenerics>['text'];\n } & QueryFilter<MessageResponse<StreamChatGenerics>['text']>\n >\n | PrimitiveFilter<MessageResponse<StreamChatGenerics>['text']>;\n } & {\n [Key in keyof Omit<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>,\n 'text'\n >]?:\n | RequireOnlyOne<\n QueryFilter<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >\n >\n | PrimitiveFilter<\n MessageResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: {};\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: StreamChatGenerics['userType'];\n }>[Key]\n >;\n }\n>;\n\nexport type PrimitiveFilter<ObjectType> = ObjectType | null;\n\nexport type QueryFilter<ObjectType = string> = NonNullable<ObjectType> extends string | number | boolean\n ? {\n $eq?: PrimitiveFilter<ObjectType>;\n $exists?: boolean;\n $gt?: PrimitiveFilter<ObjectType>;\n $gte?: PrimitiveFilter<ObjectType>;\n $in?: PrimitiveFilter<ObjectType>[];\n $lt?: PrimitiveFilter<ObjectType>;\n $lte?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $ne?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $nin?: PrimitiveFilter<ObjectType>[];\n }\n : {\n $eq?: PrimitiveFilter<ObjectType>;\n $exists?: boolean;\n $in?: PrimitiveFilter<ObjectType>[];\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $ne?: PrimitiveFilter<ObjectType>;\n /**\n * @deprecated and will be removed in a future release. Filtering shall be applied client-side.\n */\n $nin?: PrimitiveFilter<ObjectType>[];\n };\n\nexport type QueryFilters<Operators = {}> = {\n [Key in keyof Operators]?: Operators[Key];\n} &\n QueryLogicalOperators<Operators>;\n\nexport type QueryLogicalOperators<Operators> = {\n $and?: ArrayOneOrMore<QueryFilters<Operators>>;\n $nor?: ArrayOneOrMore<QueryFilters<Operators>>;\n $or?: ArrayTwoOrMore<QueryFilters<Operators>>;\n};\n\nexport type UserFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n ContainsOperator<StreamChatGenerics['userType']> & {\n id?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['id'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['id']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['id']>;\n name?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['name'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['name']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['name']>;\n notifications_muted?:\n | RequireOnlyOne<{\n $eq?: PrimitiveFilter<UserResponse<StreamChatGenerics>['notifications_muted']>;\n }>\n | boolean;\n teams?:\n | RequireOnlyOne<{\n $contains?: PrimitiveFilter<string>;\n $eq?: PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n $in?: PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n }>\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['teams']>;\n username?:\n | RequireOnlyOne<\n { $autocomplete?: UserResponse<StreamChatGenerics>['username'] } & QueryFilter<\n UserResponse<StreamChatGenerics>['username']\n >\n >\n | PrimitiveFilter<UserResponse<StreamChatGenerics>['username']>;\n } & {\n [Key in keyof Omit<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>,\n 'id' | 'name' | 'teams' | 'username'\n >]?:\n | RequireOnlyOne<\n QueryFilter<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>[Key]\n >\n >\n | PrimitiveFilter<\n UserResponse<{\n attachmentType: StreamChatGenerics['attachmentType'];\n channelType: StreamChatGenerics['channelType'];\n commandType: StreamChatGenerics['commandType'];\n eventType: StreamChatGenerics['eventType'];\n memberType: StreamChatGenerics['memberType'];\n messageType: StreamChatGenerics['messageType'];\n pollOptionType: StreamChatGenerics['pollOptionType'];\n pollType: StreamChatGenerics['pollType'];\n reactionType: StreamChatGenerics['reactionType'];\n userType: {};\n }>[Key]\n >;\n }\n>;\n\nexport type InviteStatus = 'pending' | 'accepted' | 'rejected';\n\n// https://getstream.io/chat/docs/react/channel_member/#update-channel-members\nexport type MemberFilters<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = QueryFilters<\n {\n banned?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['banned'] }\n | ChannelMemberResponse<StreamChatGenerics>['banned'];\n channel_role?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['channel_role'] }\n | ChannelMemberResponse<StreamChatGenerics>['channel_role'];\n cid?: { $eq?: ChannelResponse<StreamChatGenerics>['cid'] } | ChannelResponse<StreamChatGenerics>['cid'];\n created_at?:\n | {\n $eq?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $gt?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $gte?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $lt?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n $lte?: ChannelMemberResponse<StreamChatGenerics>['created_at'];\n }\n | ChannelMemberResponse<StreamChatGenerics>['created_at'];\n id?:\n | RequireOnlyOne<{\n $eq?: UserResponse<StreamChatGenerics>['id'];\n $in?: UserResponse<StreamChatGenerics>['id'][];\n }>\n | UserResponse<StreamChatGenerics>['id'];\n invite?:\n | { $eq?: ChannelMemberResponse<StreamChatGenerics>['status'] }\n | ChannelMemberResponse<StreamChatGenerics>['status'];\n joined?: { $eq?: boolean } | boolean;\n last_active?:\n | {\n $eq?: UserResponse<StreamChatGenerics>['last_active'];\n $gt?: UserResponse<StreamChatGenerics>['last_active'];\n $gte?: UserResponse<StreamChatGenerics>['last_active'];\n $lt?: UserResponse<StreamChatGenerics>['last_active'];\n $lte?: UserResponse<StreamChatGenerics>['last_active'];\n }\n | UserResponse<StreamChatGenerics>['last_active'];\n name?:\n | RequireOnlyOne<{\n $autocomplete?: ChannelMemberResponse<StreamChatGenerics>['name'];\n $eq?: ChannelMemberResponse<StreamChatGenerics>['name'];\n $in?: ChannelMemberResponse<StreamChatGenerics>['name'][];\n $q?: ChannelMemberResponse<StreamChatGenerics>['name'];\n }>\n | PrimitiveFilter<ChannelMemberResponse<StreamChatGenerics>['name']>;\n updated_at?:\n | {\n $eq?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $gt?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $gte?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $lt?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n $lte?: ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n }\n | ChannelMemberResponse<StreamChatGenerics>['updated_at'];\n 'user.email'?:\n | RequireOnlyOne<{\n $autocomplete?: string;\n $eq?: string;\n $in?: string;\n }>\n | string;\n user_id?:\n | RequireOnlyOne<{\n $eq?: ChannelMemberResponse<StreamChatGenerics>['user_id'];\n $in?: ChannelMemberResponse<StreamChatGenerics>['user_id'][];\n }>\n | PrimitiveFilter<ChannelMemberResponse<StreamChatGenerics>['id']>;\n } & {\n [Key in keyof ContainsOperator<StreamChatGenerics['memberType']>]?:\n | RequireOnlyOne<QueryFilter<ContainsOperator<StreamChatGenerics['memberType']>[Key]>>\n | PrimitiveFilter<ContainsOperator<StreamChatGenerics['memberType']>[Key]>;\n }\n>;\n\n/**\n * Sort Types\n */\n\nexport type BannedUsersSort = BannedUsersSortBase | Array<BannedUsersSortBase>;\n\nexport type BannedUsersSortBase = { created_at?: AscDesc };\n\nexport type ReactionSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | ReactionSortBase<StreamChatGenerics>\n | Array<ReactionSortBase<StreamChatGenerics>>;\n\nexport type ReactionSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['reactionType']\n> & {\n created_at?: AscDesc;\n};\n\nexport type ChannelSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | ChannelSortBase<StreamChatGenerics>\n | Array<ChannelSortBase<StreamChatGenerics>>\n | { pinned_at: AscDesc };\n\nexport type ChannelSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['channelType']\n> & {\n created_at?: AscDesc;\n has_unread?: AscDesc;\n last_message_at?: AscDesc;\n last_updated?: AscDesc;\n member_count?: AscDesc;\n unread_count?: AscDesc;\n updated_at?: AscDesc;\n};\n\nexport type PinnedMessagesSort = PinnedMessagesSortBase | Array<PinnedMessagesSortBase>;\nexport type PinnedMessagesSortBase = { pinned_at?: AscDesc };\n\nexport type Sort<T> = {\n [P in keyof T]?: AscDesc;\n};\n\nexport type UserSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | Sort<UserResponse<StreamChatGenerics>>\n | Array<Sort<UserResponse<StreamChatGenerics>>>;\n\nexport type MemberSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | Sort<Pick<UserResponse<StreamChatGenerics>, 'id' | 'created_at' | 'last_active' | 'name' | 'updated_at'>>\n | Array<Sort<Pick<UserResponse<StreamChatGenerics>, 'id' | 'created_at' | 'last_active' | 'name' | 'updated_at'>>>;\n\nexport type SearchMessageSortBase<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Sort<\n StreamChatGenerics['messageType']\n> & {\n attachments?: AscDesc;\n 'attachments.type'?: AscDesc;\n created_at?: AscDesc;\n id?: AscDesc;\n 'mentioned_users.id'?: AscDesc;\n parent_id?: AscDesc;\n pinned?: AscDesc;\n relevance?: AscDesc;\n reply_count?: AscDesc;\n text?: AscDesc;\n type?: AscDesc;\n updated_at?: AscDesc;\n 'user.id'?: AscDesc;\n};\n\nexport type SearchMessageSort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | SearchMessageSortBase<StreamChatGenerics>\n | Array<SearchMessageSortBase<StreamChatGenerics>>;\n\nexport type QuerySort<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | BannedUsersSort\n | ChannelSort<StreamChatGenerics>\n | SearchMessageSort<StreamChatGenerics>\n | UserSort<StreamChatGenerics>;\n\nexport type PollSort = PollSortBase | Array<PollSortBase>;\n\nexport type PollSortBase = {\n created_at?: AscDesc;\n id?: AscDesc;\n is_closed?: AscDesc;\n name?: AscDesc;\n updated_at?: AscDesc;\n};\n\nexport type VoteSort = VoteSortBase | Array<VoteSortBase>;\n\nexport type VoteSortBase = {\n created_at?: AscDesc;\n id?: AscDesc;\n is_closed?: AscDesc;\n name?: AscDesc;\n updated_at?: AscDesc;\n};\n\n/**\n * Base Types\n */\n\nexport type Action = {\n name?: string;\n style?: string;\n text?: string;\n type?: string;\n value?: string;\n};\n\nexport type AnonUserType = {};\n\nexport type APNConfig = {\n auth_key?: string;\n auth_type?: string;\n bundle_id?: string;\n development?: boolean;\n enabled?: boolean;\n host?: string;\n key_id?: string;\n notification_template?: string;\n p12_cert?: string;\n team_id?: string;\n};\n\nexport type AgoraOptions = {\n app_certificate: string;\n app_id: string;\n role_map?: Record<string, string>;\n};\n\nexport type HMSOptions = {\n app_access_key: string;\n app_secret: string;\n default_role: string;\n default_room_template: string;\n default_region?: string;\n role_map?: Record<string, string>;\n};\n\nexport type AsyncModerationOptions = {\n callback?: {\n mode?: 'CALLBACK_MODE_NONE' | 'CALLBACK_MODE_REST' | 'CALLBACK_MODE_TWIRP';\n server_url?: string;\n };\n timeout_ms?: number;\n};\n\nexport type AppSettings = {\n agora_options?: AgoraOptions | null;\n allowed_flag_reasons?: string[];\n apn_config?: {\n auth_key?: string;\n auth_type?: string;\n bundle_id?: string;\n development?: boolean;\n host?: string;\n key_id?: string;\n notification_template?: string;\n p12_cert?: string;\n team_id?: string;\n };\n async_moderation_config?: AsyncModerationOptions;\n async_url_enrich_enabled?: boolean;\n auto_translation_enabled?: boolean;\n before_message_send_hook_url?: string;\n cdn_expiration_seconds?: number;\n custom_action_handler_url?: string;\n disable_auth_checks?: boolean;\n disable_permissions_checks?: boolean;\n enforce_unique_usernames?: 'no' | 'app' | 'team';\n // all possible file mime types are https://www.iana.org/assignments/media-types/media-types.xhtml\n file_upload_config?: FileUploadConfig;\n firebase_config?: {\n apn_template?: string;\n credentials_json?: string;\n data_template?: string;\n notification_template?: string;\n server_key?: string;\n };\n grants?: Record<string, string[]>;\n hms_options?: HMSOptions | null;\n huawei_config?: {\n id: string;\n secret: string;\n };\n image_moderation_enabled?: boolean;\n image_upload_config?: FileUploadConfig;\n migrate_permissions_to_v2?: boolean;\n multi_tenant_enabled?: boolean;\n permission_version?: 'v1' | 'v2';\n push_config?: {\n offline_only?: boolean;\n version?: string;\n };\n reminders_interval?: number;\n revoke_tokens_issued_before?: string | null;\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n video_provider?: string;\n webhook_events?: Array<string> | null;\n webhook_url?: string;\n xiaomi_config?: {\n package_name: string;\n secret: string;\n };\n};\n\nexport type Attachment<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['attachmentType'] & {\n actions?: Action[];\n asset_url?: string;\n author_icon?: string;\n author_link?: string;\n author_name?: string;\n color?: string;\n duration?: number;\n fallback?: string;\n fields?: Field[];\n file_size?: number | string;\n footer?: string;\n footer_icon?: string;\n giphy?: GiphyData;\n image_url?: string;\n mime_type?: string;\n latitude?: number;\n longitude?: number;\n og_scrape_url?: string;\n original_height?: number;\n original_width?: number;\n pretext?: string;\n text?: string;\n thumb_url?: string;\n title?: string;\n title_link?: string;\n type?: string;\n waveform_data?: Array<number>;\n};\n\nexport type OGAttachment = {\n og_scrape_url: string;\n asset_url?: string; // og:video | og:audio\n author_link?: string; // og:site\n author_name?: string; // og:site_name\n image_url?: string; // og:image\n text?: string; // og:description\n thumb_url?: string; // og:image\n title?: string; // og:title\n title_link?: string; // og:url\n type?: string | 'video' | 'audio' | 'image';\n};\n\nexport type BlockList = {\n name: string;\n words: string[];\n type?: string;\n validate?: boolean;\n};\n\nexport type ChannelConfig<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = ChannelConfigFields &\n CreatedAtUpdatedAt & {\n commands?: CommandVariants<StreamChatGenerics>[];\n };\n\nexport type ChannelConfigAutomod = '' | 'AI' | 'disabled' | 'simple';\n\nexport type ChannelConfigAutomodBehavior = '' | 'block' | 'flag';\n\nexport type ChannelConfigAutomodThresholds = null | {\n explicit?: { block?: number; flag?: number };\n spam?: { block?: number; flag?: number };\n toxic?: { block?: number; flag?: number };\n};\n\nexport type ChannelConfigFields = {\n reminders: boolean;\n automod?: ChannelConfigAutomod;\n automod_behavior?: ChannelConfigAutomodBehavior;\n automod_thresholds?: ChannelConfigAutomodThresholds;\n blocklist_behavior?: ChannelConfigAutomodBehavior;\n connect_events?: boolean;\n custom_events?: boolean;\n mark_messages_pending?: boolean;\n max_message_length?: number;\n message_retention?: string;\n mutes?: boolean;\n name?: string;\n polls?: boolean;\n push_notifications?: boolean;\n quotes?: boolean;\n reactions?: boolean;\n read_events?: boolean;\n replies?: boolean;\n search?: boolean;\n typing_events?: boolean;\n uploads?: boolean;\n url_enrichment?: boolean;\n};\n\nexport type ChannelConfigWithInfo<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ChannelConfigFields &\n CreatedAtUpdatedAt & {\n commands?: CommandResponse<StreamChatGenerics>[];\n };\n\nexport type ChannelData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['channelType'] & {\n blocked?: boolean;\n members?: string[] | Array<NewMemberPayload<StreamChatGenerics>>;\n name?: string;\n};\n\n/**\n * @deprecated Use ChannelMemberResponse instead\n */\nexport type ChannelMembership<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = ChannelMemberResponse<StreamChatGenerics>;\n\nexport type ChannelMute<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n channel?: ChannelResponse<StreamChatGenerics>;\n created_at?: string;\n expires?: string;\n updated_at?: string;\n};\n\nexport type ChannelRole = {\n custom?: boolean;\n name?: string;\n owner?: boolean;\n resource?: string;\n same_team?: boolean;\n};\n\nexport type CheckPushInput<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n apn_template?: string;\n client_id?: string;\n connection_id?: string;\n firebase_data_template?: string;\n firebase_template?: string;\n message_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PushProvider = 'apn' | 'firebase' | 'huawei' | 'xiaomi';\n\nexport type PushProviderConfig = PushProviderCommon &\n PushProviderID &\n PushProviderAPN &\n PushProviderFirebase &\n PushProviderHuawei &\n PushProviderXiaomi;\n\nexport type PushProviderID = {\n name: string;\n type: PushProvider;\n};\n\nexport type PushProviderCommon = {\n created_at: string;\n updated_at: string;\n description?: string;\n disabled_at?: string;\n disabled_reason?: string;\n};\n\nexport type PushProviderAPN = {\n apn_auth_key?: string;\n apn_auth_type?: 'token' | 'certificate';\n apn_development?: boolean;\n apn_host?: string;\n apn_key_id?: string;\n apn_notification_template?: string;\n apn_p12_cert?: string;\n apn_team_id?: string;\n apn_topic?: string;\n};\n\nexport type PushProviderFirebase = {\n firebase_apn_template?: string;\n firebase_credentials?: string;\n firebase_data_template?: string;\n firebase_notification_template?: string;\n firebase_server_key?: string;\n};\n\nexport type PushProviderHuawei = {\n huawei_app_id?: string;\n huawei_app_secret?: string;\n};\n\nexport type PushProviderXiaomi = {\n xiaomi_package_name?: string;\n xiaomi_secret?: string;\n};\n\nexport type CommandVariants<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n | 'all'\n | 'ban'\n | 'fun_set'\n | 'giphy'\n | 'moderation_set'\n | 'mute'\n | 'unban'\n | 'unmute'\n | StreamChatGenerics['commandType'];\n\nexport type Configs<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n ChannelConfigWithInfo<StreamChatGenerics> | undefined\n>;\n\nexport type ConnectionOpen<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n connection_id: string;\n cid?: string;\n created_at?: string;\n me?: OwnUserResponse<StreamChatGenerics>;\n type?: string;\n};\n\nexport type CreatedAtUpdatedAt = {\n created_at: string;\n updated_at: string;\n};\n\nexport type Device<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = DeviceFields & {\n provider?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type BaseDeviceFields = {\n id: string;\n push_provider: PushProvider;\n push_provider_name?: string;\n};\n\nexport type DeviceFields = BaseDeviceFields & {\n created_at: string;\n disabled?: boolean;\n disabled_reason?: string;\n};\n\nexport type EndpointName =\n | 'Connect'\n | 'LongPoll'\n | 'DeleteFile'\n | 'DeleteImage'\n | 'DeleteMessage'\n | 'DeleteUser'\n | 'DeleteUsers'\n | 'DeactivateUser'\n | 'ExportUser'\n | 'DeleteReaction'\n | 'UpdateChannel'\n | 'UpdateChannelPartial'\n | 'UpdateMessage'\n | 'UpdateMessagePartial'\n | 'GetMessage'\n | 'GetManyMessages'\n | 'UpdateUsers'\n | 'UpdateUsersPartial'\n | 'CreateGuest'\n | 'GetOrCreateChannel'\n | 'StopWatchingChannel'\n | 'QueryChannels'\n | 'Search'\n | 'QueryUsers'\n | 'QueryMembers'\n | 'QueryBannedUsers'\n | 'QueryFlags'\n | 'QueryMessageFlags'\n | 'GetReactions'\n | 'GetReplies'\n | 'GetPinnedMessages'\n | 'Ban'\n | 'Unban'\n | 'MuteUser'\n | 'MuteChannel'\n | 'UnmuteChannel'\n | 'UnmuteUser'\n | 'RunMessageAction'\n | 'SendEvent'\n | 'SendUserCustomEvent'\n | 'MarkRead'\n | 'MarkChannelsRead'\n | 'SendMessage'\n | 'ImportChannelMessages'\n | 'UploadFile'\n | 'UploadImage'\n | 'UpdateApp'\n | 'GetApp'\n | 'CreateDevice'\n | 'DeleteDevice'\n | 'SendReaction'\n | 'Flag'\n | 'Unflag'\n | 'Unblock'\n | 'QueryFlagReports'\n | 'FlagReportReview'\n | 'CreateChannelType'\n | 'DeleteChannel'\n | 'DeleteChannels'\n | 'DeleteChannelType'\n | 'GetChannelType'\n | 'ListChannelTypes'\n | 'ListDevices'\n | 'TruncateChannel'\n | 'UpdateChannelType'\n | 'CheckPush'\n | 'PrivateSubmitModeration'\n | 'ReactivateUser'\n | 'HideChannel'\n | 'ShowChannel'\n | 'CreatePermission'\n | 'UpdatePermission'\n | 'GetPermission'\n | 'DeletePermission'\n | 'ListPermissions'\n | 'CreateRole'\n | 'DeleteRole'\n | 'ListRoles'\n | 'ListCustomRoles'\n | 'Sync'\n | 'TranslateMessage'\n | 'CreateCommand'\n | 'GetCommand'\n | 'UpdateCommand'\n | 'DeleteCommand'\n | 'ListCommands'\n | 'CreateBlockList'\n | 'UpdateBlockList'\n | 'GetBlockList'\n | 'ListBlockLists'\n | 'DeleteBlockList'\n | 'ExportChannels'\n | 'GetExportChannelsStatus'\n | 'CheckSQS'\n | 'GetRateLimits'\n | 'CreateSegment'\n | 'GetSegment'\n | 'QuerySegments'\n | 'UpdateSegment'\n | 'DeleteSegment'\n | 'CreateCampaign'\n | 'GetCampaign'\n | 'ListCampaigns'\n | 'UpdateCampaign'\n | 'DeleteCampaign'\n | 'ScheduleCampaign'\n | 'StopCampaign'\n | 'ResumeCampaign'\n | 'TestCampaign'\n | 'GetOG'\n | 'GetTask'\n | 'ExportUsers'\n | 'CreateImport'\n | 'CreateImportURL'\n | 'GetImport'\n | 'ListImports'\n | 'UpsertPushProvider'\n | 'DeletePushProvider'\n | 'ListPushProviders'\n | 'CreatePoll';\n\nexport type ExportChannelRequest = {\n id: string;\n type: string;\n cid?: string;\n messages_since?: Date;\n messages_until?: Date;\n};\n\nexport type ExportChannelOptions = {\n clear_deleted_message_text?: boolean;\n export_users?: boolean;\n include_soft_deleted_channels?: boolean;\n include_truncated_messages?: boolean;\n version?: string;\n};\n\nexport type ExportUsersRequest = {\n user_ids: string[];\n};\n\nexport type Field = {\n short?: boolean;\n title?: string;\n value?: string;\n};\n\nexport type FileUploadConfig = {\n allowed_file_extensions?: string[] | null;\n allowed_mime_types?: string[] | null;\n blocked_file_extensions?: string[] | null;\n blocked_mime_types?: string[] | null;\n size_limit?: number | null;\n};\n\nexport type FirebaseConfig = {\n apn_template?: string;\n credentials_json?: string;\n data_template?: string;\n enabled?: boolean;\n notification_template?: string;\n server_key?: string;\n};\n\ntype GiphyVersionInfo = {\n height: string;\n url: string;\n width: string;\n frames?: string;\n size?: string;\n};\n\ntype GiphyVersions =\n | 'original'\n | 'fixed_height'\n | 'fixed_height_still'\n | 'fixed_height_downsampled'\n | 'fixed_width'\n | 'fixed_width_still'\n | 'fixed_width_downsampled';\n\ntype GiphyData = {\n [key in GiphyVersions]: GiphyVersionInfo;\n};\n\nexport type HuaweiConfig = {\n enabled?: boolean;\n id?: string;\n secret?: string;\n};\n\nexport type XiaomiConfig = {\n enabled?: boolean;\n package_name?: string;\n secret?: string;\n};\n\nexport type LiteralStringForUnion = string & {};\n\nexport type LogLevel = 'info' | 'error' | 'warn';\n\nexport type Logger = (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => void;\n\nexport type Message<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n MessageBase<StreamChatGenerics>\n> & {\n mentioned_users?: string[];\n};\n\nexport type MessageBase<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['messageType'] & {\n id: string;\n attachments?: Attachment<StreamChatGenerics>[];\n html?: string;\n mml?: string;\n parent_id?: string;\n pin_expires?: string | null;\n pinned?: boolean;\n pinned_at?: string | null;\n poll_id?: string;\n quoted_message_id?: string;\n show_in_channel?: boolean;\n silent?: boolean;\n text?: string;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type MessageLabel = 'deleted' | 'ephemeral' | 'error' | 'regular' | 'reply' | 'system';\n\nexport type SendMessageOptions = {\n force_moderation?: boolean;\n is_pending_message?: boolean;\n keep_channel_hidden?: boolean;\n pending?: boolean;\n pending_message_metadata?: Record<string, string>;\n skip_enrich_url?: boolean;\n skip_push?: boolean;\n};\n\nexport type UpdateMessageOptions = {\n skip_enrich_url?: boolean;\n};\n\nexport type GetMessageOptions = {\n show_deleted_message?: boolean;\n};\n\nexport type Mute<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n target: UserResponse<StreamChatGenerics>;\n updated_at: string;\n user: UserResponse<StreamChatGenerics>;\n};\n\nexport type PartialUpdateChannel<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<ChannelResponse<StreamChatGenerics>>;\n unset?: Array<keyof ChannelResponse<StreamChatGenerics>>;\n};\n\nexport type PartialUpdateMember<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: ChannelMemberUpdates<StreamChatGenerics>;\n unset?: Array<keyof ChannelMemberUpdates<StreamChatGenerics>>;\n};\n\nexport type PartialUserUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n id: string;\n set?: Partial<UserResponse<StreamChatGenerics>>;\n unset?: Array<keyof UserResponse<StreamChatGenerics>>;\n};\n\nexport type MessageUpdatableFields<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<StreamChatGenerics>,\n 'cid' | 'created_at' | 'updated_at' | 'deleted_at' | 'user' | 'user_id'\n>;\n\nexport type PartialMessageUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<MessageUpdatableFields<StreamChatGenerics>>;\n unset?: Array<keyof MessageUpdatableFields<StreamChatGenerics>>;\n};\n\nexport type PendingMessageResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message: MessageResponse<StreamChatGenerics>;\n pending_message_metadata?: Record<string, string>;\n};\n\nexport type PermissionAPIObject = {\n action?: string;\n condition?: object;\n custom?: boolean;\n description?: string;\n id?: string;\n level?: string;\n name?: string;\n owner?: boolean;\n same_team?: boolean;\n tags?: string[];\n};\n\nexport type PermissionObject = {\n action?: 'Deny' | 'Allow';\n name?: string;\n owner?: boolean;\n priority?: number;\n resources?: string[];\n roles?: string[];\n};\n\nexport type Policy = {\n action?: 0 | 1;\n created_at?: string;\n name?: string;\n owner?: boolean;\n priority?: number;\n resources?: string[];\n roles?: string[] | null;\n updated_at?: string;\n};\n\nexport type RateLimitsInfo = {\n limit: number;\n remaining: number;\n reset: number;\n};\n\nexport type RateLimitsMap = Record<EndpointName, RateLimitsInfo>;\n\nexport type Reaction<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['reactionType'] & {\n type: string;\n message_id?: string;\n score?: number;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type Resource =\n | 'AddLinks'\n | 'BanUser'\n | 'CreateChannel'\n | 'CreateMessage'\n | 'CreateReaction'\n | 'DeleteAttachment'\n | 'DeleteChannel'\n | 'DeleteMessage'\n | 'DeleteReaction'\n | 'EditUser'\n | 'MuteUser'\n | 'ReadChannel'\n | 'RunMessageAction'\n | 'UpdateChannel'\n | 'UpdateChannelMembers'\n | 'UpdateMessage'\n | 'UpdateUser'\n | 'UploadAttachment';\n\nexport type SearchPayload<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n SearchOptions<StreamChatGenerics>,\n 'sort'\n> & {\n client_id?: string;\n connection_id?: string;\n filter_conditions?: ChannelFilters<StreamChatGenerics>;\n message_filter_conditions?: MessageFilters<StreamChatGenerics>;\n query?: string;\n sort?: Array<{\n direction: AscDesc;\n field: keyof SearchMessageSortBase<StreamChatGenerics>;\n }>;\n};\n\nexport type TestPushDataInput = {\n apnTemplate?: string;\n firebaseDataTemplate?: string;\n firebaseTemplate?: string;\n messageID?: string;\n pushProviderName?: string;\n pushProviderType?: PushProvider;\n skipDevices?: boolean;\n};\n\nexport type TestSQSDataInput = {\n sqs_key?: string;\n sqs_secret?: string;\n sqs_url?: string;\n};\n\nexport type TestSNSDataInput = {\n sns_key?: string;\n sns_secret?: string;\n sns_topic_arn?: string;\n};\n\nexport type TokenOrProvider = null | string | TokenProvider | undefined;\n\nexport type TokenProvider = () => Promise<string>;\n\nexport type TranslationLanguages =\n | ''\n | 'af'\n | 'am'\n | 'ar'\n | 'az'\n | 'bg'\n | 'bn'\n | 'bs'\n | 'cs'\n | 'da'\n | 'de'\n | 'el'\n | 'en'\n | 'es'\n | 'es-MX'\n | 'et'\n | 'fa'\n | 'fa-AF'\n | 'fi'\n | 'fr'\n | 'fr-CA'\n | 'ha'\n | 'he'\n | 'hi'\n | 'hr'\n | 'hu'\n | 'id'\n | 'it'\n | 'ja'\n | 'ka'\n | 'ko'\n | 'lt'\n | 'lv'\n | 'ms'\n | 'nl'\n | 'no'\n | 'pl'\n | 'ps'\n | 'pt'\n | 'ro'\n | 'ru'\n | 'sk'\n | 'sl'\n | 'so'\n | 'sq'\n | 'sr'\n | 'sv'\n | 'sw'\n | 'ta'\n | 'th'\n | 'tl'\n | 'tr'\n | 'uk'\n | 'ur'\n | 'vi'\n | 'zh'\n | 'zh-TW';\n\nexport type TypingStartEvent = Event;\n\nexport type ReservedMessageFields =\n | 'command'\n | 'created_at'\n | 'html'\n | 'latest_reactions'\n | 'own_reactions'\n | 'quoted_message'\n | 'reaction_counts'\n | 'reply_count'\n | 'type'\n | 'updated_at'\n | 'user'\n | '__html';\n\nexport type UpdatedMessage<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<StreamChatGenerics>,\n 'mentioned_users'\n> & { mentioned_users?: string[] };\n\nexport type User<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = StreamChatGenerics['userType'] & {\n id: string;\n anon?: boolean;\n name?: string;\n role?: string;\n teams?: string[];\n username?: string;\n};\n\nexport type TaskResponse = {\n task_id: string;\n};\n\nexport type DeleteChannelsResponse = {\n result: Record<string, string>;\n} & Partial<TaskResponse>;\n\nexport type DeleteType = 'soft' | 'hard' | 'pruning';\n\n/*\n DeleteUserOptions specifies a collection of one or more `user_ids` to be deleted.\n\n `user`:\n - soft: marks user as deleted and retains all user data\n - pruning: marks user as deleted and nullifies user information\n - hard: deletes user completely - this requires hard option for messages and conversation as well\n `conversations`:\n - soft: marks all conversation channels as deleted (same effect as Delete Channels with 'hard' option disabled)\n - hard: deletes channel and all its data completely including messages (same effect as Delete Channels with 'hard' option enabled)\n `messages`:\n - soft: marks all user messages as deleted without removing any related message data\n - pruning: marks all user messages as deleted, nullifies message information and removes some message data such as reactions and flags\n - hard: deletes messages completely with all related information\n `new_channel_owner_id`: any channels owned by the hard-deleted user will be transferred to this user ID\n */\nexport type DeleteUserOptions = {\n conversations?: Exclude<DeleteType, 'pruning'>;\n messages?: DeleteType;\n new_channel_owner_id?: string;\n user?: DeleteType;\n};\n\nexport type SegmentType = 'channel' | 'user';\n\nexport type SegmentData = {\n all_sender_channels?: boolean;\n all_users?: boolean;\n description?: string;\n filter?: {};\n name?: string;\n};\n\nexport type SegmentResponse = {\n created_at: string;\n deleted_at: string;\n id: string;\n locked: boolean;\n size: number;\n task_id: string;\n type: SegmentType;\n updated_at: string;\n} & SegmentData;\n\nexport type UpdateSegmentData = {\n name: string;\n} & SegmentData;\n\nexport type SegmentTargetsResponse = {\n created_at: string;\n segment_id: string;\n target_id: string;\n};\n\nexport type SortParam = {\n field: string;\n direction?: AscDesc;\n};\n\nexport type Pager = {\n limit?: number;\n next?: string;\n prev?: string;\n};\n\nexport type QuerySegmentsOptions = Pager;\n\nexport type QuerySegmentTargetsFilter = {\n target_id?: {\n $eq?: string;\n $gte?: string;\n $in?: string[];\n $lte?: string;\n };\n};\nexport type QuerySegmentTargetsOptions = Pick<Pager, 'next' | 'limit'>;\n\nexport type CampaignSort = {\n field: string;\n direction?: number;\n}[];\n\nexport type CampaignQueryOptions = {\n limit?: number;\n next?: string;\n prev?: string;\n sort?: CampaignSort;\n};\n\nexport type SegmentQueryOptions = CampaignQueryOptions;\n\n// TODO: add better typing\nexport type CampaignFilters = {};\n\nexport type CampaignData = {\n channel_template?: {\n type: string;\n custom?: {};\n id?: string;\n members?: string[];\n };\n create_channels?: boolean;\n deleted_at?: string;\n description?: string;\n id?: string | null;\n message_template?: {\n text: string;\n attachments?: Attachment[];\n custom?: {};\n poll_id?: string;\n };\n name?: string;\n segment_ids?: string[];\n sender_id?: string;\n skip_push?: boolean;\n skip_webhook?: boolean;\n user_ids?: string[];\n};\n\nexport type CampaignStats = {\n progress?: number;\n stats_channels_created?: number;\n stats_completed_at?: string;\n stats_messages_sent?: number;\n stats_started_at?: string;\n};\nexport type CampaignResponse = {\n created_at: string;\n id: string;\n segments: SegmentResponse[];\n sender: UserResponse;\n stats: CampaignStats;\n status: 'draft' | 'scheduled' | 'in_progress' | 'completed' | 'stopped';\n updated_at: string;\n users: UserResponse[];\n scheduled_for?: string;\n} & CampaignData;\n\nexport type DeleteCampaignOptions = {};\n\nexport type TaskStatus = {\n created_at: string;\n status: string;\n task_id: string;\n updated_at: string;\n error?: {\n description: string;\n type: string;\n };\n result?: UR;\n};\n\nexport type TruncateOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n hard_delete?: boolean;\n message?: Message<StreamChatGenerics>;\n skip_push?: boolean;\n truncated_at?: Date;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type CreateImportURLResponse = {\n path: string;\n upload_url: string;\n};\n\nexport type CreateImportResponse = {\n import_task: ImportTask;\n};\n\nexport type GetImportResponse = {\n import_task: ImportTask;\n};\n\nexport type CreateImportOptions = {\n mode: 'insert' | 'upsert';\n};\n\nexport type ListImportsPaginationOptions = {\n limit?: number;\n offset?: number;\n};\n\nexport type ListImportsResponse = {\n import_tasks: ImportTask[];\n};\n\nexport type ImportTaskHistory = {\n created_at: string;\n next_state: string;\n prev_state: string;\n};\n\nexport type ImportTask = {\n created_at: string;\n history: ImportTaskHistory[];\n id: string;\n path: string;\n state: string;\n updated_at: string;\n result?: UR;\n size?: number;\n};\n\nexport type MessageSetType = 'latest' | 'current' | 'new';\nexport type MessageSet<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n isCurrent: boolean;\n isLatest: boolean;\n messages: FormatMessageResponse<StreamChatGenerics>[];\n pagination: { hasNext: boolean; hasPrev: boolean };\n};\n\nexport type PushProviderUpsertResponse = {\n push_provider: PushProvider;\n};\n\nexport type PushProviderListResponse = {\n push_providers: PushProvider[];\n};\n\nexport type CreateCallOptions<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n id: string;\n type: string;\n options?: UR;\n user?: UserResponse<StreamChatGenerics> | null;\n user_id?: string;\n};\n\nexport type HMSCall = {\n room: string;\n};\n\nexport type AgoraCall = {\n channel: string;\n};\n\nexport type Call = {\n id: string;\n provider: string;\n agora?: AgoraCall;\n hms?: HMSCall;\n};\n\nexport type CreateCallResponse = APIResponse & {\n call: Call;\n token: string;\n agora_app_id?: string;\n agora_uid?: number;\n};\n\nexport type GetCallTokenResponse = APIResponse & {\n token: string;\n agora_app_id?: string;\n agora_uid?: number;\n};\n\ntype ErrorResponseDetails = {\n code: number;\n messages: string[];\n};\n\nexport type APIErrorResponse = {\n code: number;\n duration: string;\n message: string;\n more_info: string;\n StatusCode: number;\n details?: ErrorResponseDetails;\n};\n\nexport class ErrorFromResponse<T> extends Error {\n code?: number;\n response?: AxiosResponse<T>;\n status?: number;\n}\n\nexport type QueryPollsResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n polls: PollResponse<StreamChatGenerics>[];\n next?: string;\n};\n\nexport type CreatePollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type GetPollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type UpdatePollAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll: PollResponse<StreamChatGenerics>;\n};\n\nexport type PollResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] &\n PollEnrichData<StreamChatGenerics> & {\n created_at: string;\n created_by: UserResponse<StreamChatGenerics> | null;\n created_by_id: string;\n enforce_unique_vote: boolean;\n id: string;\n max_votes_allowed: number;\n name: string;\n options: PollOption<StreamChatGenerics>[];\n updated_at: string;\n allow_answers?: boolean;\n allow_user_suggested_options?: boolean;\n description?: string;\n is_closed?: boolean;\n voting_visibility?: VotingVisibility;\n };\n\nexport type PollOption<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n id: string;\n poll_id: string;\n text: string;\n updated_at: string;\n vote_count: number;\n votes?: PollVote<StreamChatGenerics>[];\n};\n\nexport enum VotingVisibility {\n anonymous = 'anonymous',\n public = 'public',\n}\n\nexport type PollEnrichData<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n answers_count: number;\n latest_answers: PollAnswer<StreamChatGenerics>[]; // not updated with WS events, ordered DESC by created_at, seems like updated_at cannot be different from created_at\n latest_votes_by_option: Record<string, PollVote<StreamChatGenerics>[]>; // not updated with WS events; always null in anonymous polls\n vote_count: number;\n vote_counts_by_option: Record<string, number>;\n own_votes?: (PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>)[]; // not updated with WS events\n};\n\nexport type PollData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] & {\n id: string;\n name: string;\n allow_answers?: boolean;\n allow_user_suggested_options?: boolean;\n description?: string;\n enforce_unique_vote?: boolean;\n is_closed?: boolean;\n max_votes_allowed?: number;\n options?: PollOptionData<StreamChatGenerics>[];\n user_id?: string;\n voting_visibility?: VotingVisibility;\n};\n\nexport type CreatePollData<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n PollData<StreamChatGenerics>\n> &\n Pick<PollData<StreamChatGenerics>, 'name'>;\n\nexport type PartialPollUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<PollData<StreamChatGenerics>>;\n unset?: Array<keyof PollData<StreamChatGenerics>>;\n};\n\nexport type PollOptionData<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollOptionType'] & {\n text: string;\n id?: string;\n position?: number;\n};\n\nexport type PartialPollOptionUpdate<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n set?: Partial<PollOptionResponse<StreamChatGenerics>>;\n unset?: Array<keyof PollOptionResponse<StreamChatGenerics>>;\n};\n\nexport type PollVoteData = {\n answer_text?: string;\n is_answer?: boolean;\n option_id?: string;\n};\n\nexport type PollPaginationOptions = {\n limit?: number;\n next?: string;\n};\n\nexport type CreatePollOptionAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n poll_option: PollOptionResponse<StreamChatGenerics>;\n};\n\nexport type GetPollOptionAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = CreatePollOptionAPIResponse<StreamChatGenerics>;\nexport type UpdatePollOptionAPIResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = CreatePollOptionAPIResponse<StreamChatGenerics>;\n\nexport type PollOptionResponse<\n StreamChatGenerics extends ExtendableGenerics = DefaultGenerics\n> = StreamChatGenerics['pollType'] & {\n created_at: string;\n id: string;\n poll_id: string;\n position: number;\n text: string;\n updated_at: string;\n vote_count: number;\n votes?: PollVote<StreamChatGenerics>[];\n};\n\nexport type PollVote<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n created_at: string;\n id: string;\n poll_id: string;\n updated_at: string;\n option_id?: string;\n user?: UserResponse<StreamChatGenerics>;\n user_id?: string;\n};\n\nexport type PollAnswer<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = Exclude<\n PollVote<StreamChatGenerics>,\n 'option_id'\n> & {\n answer_text: string;\n is_answer: boolean; // this is absolutely redundant prop as answer_text indicates that a vote is an answer\n};\n\nexport type PollVotesAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n votes: (PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>)[];\n next?: string;\n};\n\nexport type PollAnswersAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n votes: PollAnswer<StreamChatGenerics>[]; // todo: should be changes to answers?\n next?: string;\n};\n\nexport type CastVoteAPIResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n vote: PollVote<StreamChatGenerics> | PollAnswer<StreamChatGenerics>;\n};\n\nexport type QueryMessageHistoryFilters = QueryFilters<\n {\n message_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageHistoryEntry['message_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageHistoryEntry['message_id']>;\n } & {\n user_id?:\n | RequireOnlyOne<Pick<QueryFilter<MessageHistoryEntry['message_updated_by_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<MessageHistoryEntry['message_updated_by_id']>;\n } & {\n created_at?:\n | RequireOnlyOne<\n Pick<QueryFilter<MessageHistoryEntry['message_updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>\n >\n | PrimitiveFilter<MessageHistoryEntry['message_updated_at']>;\n }\n>;\n\nexport type QueryMessageHistorySort = QueryMessageHistorySortBase | Array<QueryMessageHistorySortBase>;\n\nexport type QueryMessageHistorySortBase = {\n message_updated_at?: AscDesc;\n message_updated_by_id?: AscDesc;\n};\n\nexport type QueryMessageHistoryOptions = Pager;\n\nexport type MessageHistoryEntry<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message_id: string;\n message_updated_at: string;\n attachments?: Attachment<StreamChatGenerics>[];\n message_updated_by_id?: string;\n text?: string;\n};\n\nexport type QueryMessageHistoryResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n message_history: MessageHistoryEntry<StreamChatGenerics>[];\n next?: string;\n prev?: string;\n};\n\n// Moderation v2\nexport type ModerationPayload = {\n created_at: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom?: Record<string, any>;\n images?: string[];\n texts?: string[];\n videos?: string[];\n};\n\nexport type ModV2ReviewStatus = 'complete' | 'flagged' | 'partial';\n\nexport type ModerationFlag = {\n created_at: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom: Record<string, any>;\n entity_creator_id: string;\n entity_id: string;\n entity_type: string;\n id: string;\n reason: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result: Record<string, any>[];\n review_queue_item_id: string;\n updated_at: string;\n user: UserResponse;\n moderation_payload?: ModerationPayload;\n moderation_payload_hash?: string;\n};\n\nexport type ReviewQueueItem = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n actions_taken: any[];\n appealed_by: string;\n assigned_to: string;\n completed_at: string;\n config_key: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n context: any[];\n created_at: string;\n created_by: string;\n entity_id: string;\n entity_type: string;\n flags: ModerationFlag[];\n has_image: boolean;\n has_text: boolean;\n has_video: boolean;\n id: string;\n moderation_payload: ModerationPayload;\n moderation_payload_hash: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: any;\n recommended_action: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n results: any;\n reviewed_at: string;\n status: string;\n updated_at: string;\n};\n\nexport type SubmitActionOptions = {\n ban?: {\n channel_ban_only?: boolean;\n reason?: string;\n timeout?: number;\n };\n delete_message?: {\n hard_delete?: boolean;\n };\n delete_user?: {\n delete_conversation_channels?: boolean;\n hard_delete?: boolean;\n mark_messages_deleted?: boolean;\n };\n restore?: {};\n unban?: {\n channel_cid?: string;\n };\n user_id?: string;\n};\n\nexport type GetUserModerationReportResponse<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n user: UserResponse<StreamChatGenerics>;\n user_blocks?: Array<{\n blocked_at: string;\n blocked_by_user_id: string;\n blocked_user_id: string;\n }>;\n user_mutes?: Mute<StreamChatGenerics>[];\n};\n\nexport type QueryModerationConfigsFilters = QueryFilters<\n {\n key?: string;\n } & {\n created_at?: PrimitiveFilter<string>;\n } & {\n updated_at?: PrimitiveFilter<string>;\n }\n>;\n\nexport type ReviewQueueFilters = QueryFilters<\n {\n assigned_to?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['assigned_to']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['assigned_to']>;\n } & {\n completed_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['completed_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['completed_at']>;\n } & {\n config_key?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['config_key']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['config_key']>;\n } & {\n entity_type?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['entity_type']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['entity_type']>;\n } & {\n created_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['created_at']>;\n } & {\n id?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['id']>;\n } & {\n entity_id?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['entity_id']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['entity_id']>;\n } & {\n reviewed?: boolean;\n } & {\n reviewed_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['reviewed_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['reviewed_at']>;\n } & {\n status?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['status']>, '$eq' | '$in'>>\n | PrimitiveFilter<ReviewQueueItem['status']>;\n } & {\n updated_at?:\n | RequireOnlyOne<Pick<QueryFilter<ReviewQueueItem['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>>\n | PrimitiveFilter<ReviewQueueItem['updated_at']>;\n } & {\n has_image?: boolean;\n } & {\n has_text?: boolean;\n } & {\n has_video?: boolean;\n }\n>;\n\nexport type ReviewQueueSort =\n | Sort<Pick<ReviewQueueItem, 'id' | 'created_at' | 'updated_at'>>\n | Array<Sort<Pick<ReviewQueueItem, 'id' | 'created_at' | 'updated_at'>>>;\n\nexport type QueryModerationConfigsSort = Array<Sort<'key' | 'created_at' | 'updated_at'>>;\n\nexport type ReviewQueuePaginationOptions = Pager;\n\nexport type ReviewQueueResponse = {\n items: ReviewQueueItem[];\n next?: string;\n prev?: string;\n};\n\nexport type ModerationConfig = {};\n\nexport type GetConfigResponse = {\n config: ModerationConfig;\n};\n\nexport type UpsertConfigResponse = {\n config: ModerationConfig;\n};\n\nexport type ModerationFlagOptions = {\n custom?: Record<string, unknown>;\n moderation_payload?: ModerationPayload;\n user_id?: string;\n};\n\nexport type ModerationMuteOptions = {\n timeout?: number;\n user_id?: string;\n};\nexport type GetUserModerationReportOptions = {\n create_user_if_not_exists?: boolean;\n include_user_blocks?: boolean;\n include_user_mutes?: boolean;\n};\n","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}","export type Patch<T> = (value: T) => T;\nexport type Handler<T> = (nextValue: T, previousValue: T | undefined) => void;\nexport type Unsubscribe = () => void;\n\nfunction isPatch<T>(value: T | Patch<T>): value is Patch<T> {\n return typeof value === 'function';\n}\n\nexport class StateStore<T extends Record<string, unknown>> {\n private handlerSet = new Set<Handler<T>>();\n\n private static logCount = 5;\n\n constructor(private value: T) {}\n\n public next = (newValueOrPatch: T | Patch<T>): void => {\n // newValue (or patch output) should never be mutated previous value\n const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;\n\n // do not notify subscribers if the value hasn't changed\n if (newValue === this.value) return;\n\n const oldValue = this.value;\n this.value = newValue;\n\n this.handlerSet.forEach((handler) => handler(this.value, oldValue));\n };\n\n public partialNext = (partial: Partial<T>): void => this.next((current) => ({ ...current, ...partial }));\n\n public getLatestValue = (): T => this.value;\n\n public subscribe = (handler: Handler<T>): Unsubscribe => {\n handler(this.value, undefined);\n this.handlerSet.add(handler);\n return () => {\n this.handlerSet.delete(handler);\n };\n };\n\n public subscribeWithSelector = <O extends Readonly<Record<string, unknown>> | Readonly<unknown[]>>(\n selector: (nextValue: T) => O,\n handler: Handler<O>,\n ) => {\n // begin with undefined to reduce amount of selector calls\n let selectedValues: O | undefined;\n\n const wrappedHandler: Handler<T> = (nextValue) => {\n const newlySelectedValues = selector(nextValue);\n\n let hasUpdatedValues = !selectedValues;\n\n if (Array.isArray(newlySelectedValues) && StateStore.logCount > 0) {\n console.warn(\n '[StreamChat]: The API of our StateStore has changed. Instead of returning an array in the selector, please return a named object of properties.',\n );\n StateStore.logCount--;\n }\n\n for (const key in selectedValues) {\n // @ts-ignore TODO: remove array support (Readonly<unknown[]>)\n if (selectedValues[key] === newlySelectedValues[key]) continue;\n hasUpdatedValues = true;\n break;\n }\n\n if (!hasUpdatedValues) return;\n\n const oldSelectedValues = selectedValues;\n selectedValues = newlySelectedValues;\n\n handler(newlySelectedValues, oldSelectedValues);\n };\n\n return this.subscribe(wrappedHandler);\n };\n}\n","import type { Channel } from './channel';\nimport type { StreamChat } from './client';\nimport { StateStore } from './store';\nimport type {\n AscDesc,\n DefaultGenerics,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n MessagePaginationOptions,\n MessageResponse,\n ReadResponse,\n ThreadResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList, findIndexInSortedArray, formatMessage, throttle } from './utils';\n\ntype QueryRepliesOptions<SCG extends ExtendableGenerics> = {\n sort?: { created_at: AscDesc }[];\n} & MessagePaginationOptions & { user?: UserResponse<SCG>; user_id?: string };\n\nexport type ThreadState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n /**\n * Determines if the thread is currently opened and on-screen. When the thread is active,\n * all new messages are immediately marked as read.\n */\n active: boolean;\n channel: Channel<SCG>;\n createdAt: Date;\n deletedAt: Date | null;\n isLoading: boolean;\n isStateStale: boolean;\n pagination: ThreadRepliesPagination;\n /**\n * Thread is identified by and has a one-to-one relation with its parent message.\n * We use parent message id as a thread id.\n */\n parentMessage: FormatMessageResponse<SCG>;\n participants: ThreadResponse<SCG>['thread_participants'];\n read: ThreadReadState;\n replies: Array<FormatMessageResponse<SCG>>;\n replyCount: number;\n updatedAt: Date | null;\n};\n\nexport type ThreadRepliesPagination = {\n isLoadingNext: boolean;\n isLoadingPrev: boolean;\n nextCursor: string | null;\n prevCursor: string | null;\n};\n\nexport type ThreadUserReadState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n lastReadAt: Date;\n unreadMessageCount: number;\n user: UserResponse<SCG>;\n lastReadMessageId?: string;\n};\n\nexport type ThreadReadState<SCG extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n ThreadUserReadState<SCG> | undefined\n>;\n\nconst DEFAULT_PAGE_LIMIT = 50;\nconst DEFAULT_SORT: { created_at: AscDesc }[] = [{ created_at: -1 }];\nconst MARK_AS_READ_THROTTLE_TIMEOUT = 1000;\n\nexport class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<ThreadState<SCG>>;\n public readonly id: string;\n\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n private failedRepliesMap: Map<string, FormatMessageResponse<SCG>> = new Map();\n\n constructor({ client, threadData }: { client: StreamChat<SCG>; threadData: ThreadResponse<SCG> }) {\n const channel = client.channel(threadData.channel.type, threadData.channel.id, {\n name: threadData.channel.name,\n });\n channel._hydrateMembers(threadData.channel.members ?? []);\n\n // For when read object is undefined and due to that unreadMessageCount for\n // the current user isn't being incremented on message.new\n const placeholderReadResponse: ReadResponse[] = client.userID\n ? [{ user: { id: client.userID }, unread_messages: 0, last_read: new Date().toISOString() }]\n : [];\n\n this.state = new StateStore<ThreadState<SCG>>({\n active: false,\n channel,\n createdAt: new Date(threadData.created_at),\n deletedAt: threadData.deleted_at ? new Date(threadData.deleted_at) : null,\n isLoading: false,\n isStateStale: false,\n pagination: repliesPaginationFromInitialThread(threadData),\n parentMessage: formatMessage(threadData.parent_message),\n participants: threadData.thread_participants,\n read: formatReadState(\n !threadData.read || threadData.read.length === 0 ? placeholderReadResponse : threadData.read,\n ),\n replies: threadData.latest_replies.map(formatMessage),\n replyCount: threadData.reply_count ?? 0,\n updatedAt: threadData.updated_at ? new Date(threadData.updated_at) : null,\n });\n\n this.id = threadData.parent_message_id;\n this.client = client;\n }\n\n get channel() {\n return this.state.getLatestValue().channel;\n }\n\n get hasStaleState() {\n return this.state.getLatestValue().isStateStale;\n }\n\n get ownUnreadCount() {\n return ownUnreadCountSelector(this.client.userID)(this.state.getLatestValue());\n }\n\n public activate = () => {\n this.state.partialNext({ active: true });\n };\n\n public deactivate = () => {\n this.state.partialNext({ active: false });\n };\n\n public reload = async () => {\n if (this.state.getLatestValue().isLoading) {\n return;\n }\n\n this.state.partialNext({ isLoading: true });\n\n try {\n const thread = await this.client.getThread(this.id, { watch: true });\n this.hydrateState(thread);\n } finally {\n this.state.partialNext({ isLoading: false });\n }\n };\n\n public hydrateState = (thread: Thread<SCG>) => {\n if (thread === this) {\n // skip if the instances are the same\n return;\n }\n\n if (thread.id !== this.id) {\n throw new Error(\"Cannot hydrate thread state with using thread's state\");\n }\n\n const {\n read,\n replyCount,\n replies,\n parentMessage,\n participants,\n createdAt,\n deletedAt,\n updatedAt,\n } = thread.state.getLatestValue();\n\n // Preserve pending replies and append them to the updated list of replies\n const pendingReplies = Array.from(this.failedRepliesMap.values());\n\n this.state.partialNext({\n read,\n replyCount,\n replies: pendingReplies.length ? replies.concat(pendingReplies) : replies,\n parentMessage,\n participants,\n createdAt,\n deletedAt,\n updatedAt,\n isStateStale: false,\n });\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) {\n // Thread is already listening for events and changes\n return;\n }\n\n this.unsubscribeFunctions.add(this.subscribeMarkActiveThreadRead());\n this.unsubscribeFunctions.add(this.subscribeReloadActiveStaleThread());\n this.unsubscribeFunctions.add(this.subscribeMarkThreadStale());\n this.unsubscribeFunctions.add(this.subscribeNewReplies());\n this.unsubscribeFunctions.add(this.subscribeRepliesRead());\n this.unsubscribeFunctions.add(this.subscribeMessageDeleted());\n this.unsubscribeFunctions.add(this.subscribeMessageUpdated());\n };\n\n private subscribeMarkActiveThreadRead = () => {\n return this.state.subscribeWithSelector(\n (nextValue) => ({\n active: nextValue.active,\n unreadMessageCount: ownUnreadCountSelector(this.client.userID)(nextValue),\n }),\n ({ active, unreadMessageCount }) => {\n if (!active || !unreadMessageCount) return;\n this.throttledMarkAsRead();\n },\n );\n };\n\n private subscribeReloadActiveStaleThread = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ active: nextValue.active, isStateStale: nextValue.isStateStale }),\n ({ active, isStateStale }) => {\n if (active && isStateStale) {\n this.reload();\n }\n },\n );\n\n private subscribeMarkThreadStale = () =>\n this.client.on('user.watching.stop', (event) => {\n const { channel } = this.state.getLatestValue();\n\n if (!this.client.userID || this.client.userID !== event.user?.id || event.channel?.cid !== channel.cid) {\n return;\n }\n\n this.state.partialNext({ isStateStale: true });\n }).unsubscribe;\n\n private subscribeNewReplies = () =>\n this.client.on('message.new', (event) => {\n if (!this.client.userID || event.message?.parent_id !== this.id) {\n return;\n }\n\n const isOwnMessage = event.message.user?.id === this.client.userID;\n const { active, read } = this.state.getLatestValue();\n\n this.upsertReplyLocally({\n message: event.message,\n // Message from current user could have been added optimistically,\n // so the actual timestamp might differ in the event\n timestampChanged: isOwnMessage,\n });\n\n if (active) {\n this.throttledMarkAsRead();\n }\n\n const nextRead: ThreadReadState = {};\n\n for (const userId of Object.keys(read)) {\n const userRead = read[userId];\n\n if (userRead) {\n let nextUserRead: ThreadUserReadState = userRead;\n\n if (userId === event.user?.id) {\n // The user who just sent a message to the thread has no unread messages\n // in that thread\n nextUserRead = {\n ...nextUserRead,\n lastReadAt: event.created_at ? new Date(event.created_at) : new Date(),\n user: event.user,\n unreadMessageCount: 0,\n };\n } else if (active && userId === this.client.userID) {\n // Do not increment unread count for the current user in an active thread\n } else {\n // Increment unread count for all users except the author of the new message\n nextUserRead = {\n ...nextUserRead,\n unreadMessageCount: userRead.unreadMessageCount + 1,\n };\n }\n\n nextRead[userId] = nextUserRead;\n }\n }\n\n this.state.partialNext({ read: nextRead });\n }).unsubscribe;\n\n private subscribeRepliesRead = () =>\n this.client.on('message.read', (event) => {\n if (!event.user || !event.created_at || !event.thread) return;\n if (event.thread.parent_message_id !== this.id) return;\n\n const userId = event.user.id;\n const createdAt = event.created_at;\n const user = event.user;\n\n this.state.next((current) => ({\n ...current,\n read: {\n ...current.read,\n [userId]: {\n lastReadAt: new Date(createdAt),\n user,\n lastReadMessageId: event.last_read_message_id,\n unreadMessageCount: 0,\n },\n },\n }));\n }).unsubscribe;\n\n private subscribeMessageDeleted = () =>\n this.client.on('message.deleted', (event) => {\n if (!event.message) return;\n\n // Deleted message is a reply of this thread\n if (event.message.parent_id === this.id) {\n if (event.hard_delete) {\n this.deleteReplyLocally({ message: event.message });\n } else {\n // Handle soft delete (updates deleted_at timestamp)\n this.upsertReplyLocally({ message: event.message });\n }\n }\n\n // Deleted message is parent message of this thread\n if (event.message.id === this.id) {\n this.updateParentMessageLocally({ message: event.message });\n }\n }).unsubscribe;\n\n private subscribeMessageUpdated = () => {\n const eventTypes: EventTypes[] = ['message.updated', 'reaction.new', 'reaction.deleted', 'reaction.updated'];\n\n const unsubscribeFunctions = eventTypes.map(\n (eventType) =>\n this.client.on(eventType, (event) => {\n if (event.message) {\n this.updateParentMessageOrReplyLocally(event.message);\n }\n }).unsubscribe,\n );\n\n return () => unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());\n };\n\n public unregisterSubscriptions = () => {\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public deleteReplyLocally = ({ message }: { message: MessageResponse<SCG> }) => {\n const { replies } = this.state.getLatestValue();\n\n const index = findIndexInSortedArray({\n needle: formatMessage(message),\n sortedArray: replies,\n sortDirection: 'ascending',\n selectValueToCompare: (reply) => reply.created_at.getTime(),\n });\n\n const actualIndex =\n replies[index]?.id === message.id ? index : replies[index - 1]?.id === message.id ? index - 1 : null;\n\n if (actualIndex === null) {\n return;\n }\n\n const updatedReplies = [...replies];\n updatedReplies.splice(actualIndex, 1);\n\n this.state.partialNext({\n replies: updatedReplies,\n });\n };\n\n public upsertReplyLocally = ({\n message,\n timestampChanged = false,\n }: {\n message: MessageResponse<SCG>;\n timestampChanged?: boolean;\n }) => {\n if (message.parent_id !== this.id) {\n throw new Error('Reply does not belong to this thread');\n }\n\n const formattedMessage = formatMessage(message);\n\n if (message.status === 'failed') {\n // store failed reply so that it's not lost when reloading or hydrating\n this.failedRepliesMap.set(formattedMessage.id, formattedMessage);\n } else if (this.failedRepliesMap.has(message.id)) {\n this.failedRepliesMap.delete(message.id);\n }\n\n this.state.next((current) => ({\n ...current,\n replies: addToMessageList(current.replies, formattedMessage, timestampChanged),\n }));\n };\n\n public updateParentMessageLocally = ({ message }: { message: MessageResponse<SCG> }) => {\n if (message.id !== this.id) {\n throw new Error('Message does not belong to this thread');\n }\n\n this.state.next((current) => {\n const formattedMessage = formatMessage(message);\n\n return {\n ...current,\n deletedAt: formattedMessage.deleted_at,\n parentMessage: formattedMessage,\n replyCount: message.reply_count ?? current.replyCount,\n };\n });\n };\n\n public updateParentMessageOrReplyLocally = (message: MessageResponse<SCG>) => {\n if (message.parent_id === this.id) {\n this.upsertReplyLocally({ message });\n }\n\n if (!message.parent_id && message.id === this.id) {\n this.updateParentMessageLocally({ message });\n }\n };\n\n public markAsRead = async ({ force = false }: { force?: boolean } = {}) => {\n if (this.ownUnreadCount === 0 && !force) {\n return null;\n }\n\n return await this.channel.markRead({ thread_id: this.id });\n };\n\n private throttledMarkAsRead = throttle(() => this.markAsRead(), MARK_AS_READ_THROTTLE_TIMEOUT, { trailing: true });\n\n public queryReplies = ({\n limit = DEFAULT_PAGE_LIMIT,\n sort = DEFAULT_SORT,\n ...otherOptions\n }: QueryRepliesOptions<SCG> = {}) => {\n return this.channel.getReplies(this.id, { limit, ...otherOptions }, sort);\n };\n\n public loadNextPage = ({ limit = DEFAULT_PAGE_LIMIT }: { limit?: number } = {}) => {\n return this.loadPage(limit);\n };\n\n public loadPrevPage = ({ limit = DEFAULT_PAGE_LIMIT }: { limit?: number } = {}) => {\n return this.loadPage(-limit);\n };\n\n private loadPage = async (count: number) => {\n const { pagination } = this.state.getLatestValue();\n const [loadingKey, cursorKey, insertionMethodKey] =\n count > 0\n ? (['isLoadingNext', 'nextCursor', 'push'] as const)\n : (['isLoadingPrev', 'prevCursor', 'unshift'] as const);\n\n if (pagination[loadingKey] || pagination[cursorKey] === null) return;\n\n const queryOptions = { [count > 0 ? 'id_gt' : 'id_lt']: pagination[cursorKey] };\n const limit = Math.abs(count);\n\n this.state.partialNext({ pagination: { ...pagination, [loadingKey]: true } });\n\n try {\n const data = await this.queryReplies({ ...queryOptions, limit });\n const replies = data.messages.map(formatMessage);\n const maybeNextCursor = replies.at(count > 0 ? -1 : 0)?.id ?? null;\n\n this.state.next((current) => {\n let nextReplies = current.replies;\n\n // prevent re-creating array if there's nothing to add to the current one\n if (replies.length > 0) {\n nextReplies = [...current.replies];\n nextReplies[insertionMethodKey](...replies);\n }\n\n return {\n ...current,\n replies: nextReplies,\n pagination: {\n ...current.pagination,\n [cursorKey]: data.messages.length < limit ? null : maybeNextCursor,\n [loadingKey]: false,\n },\n };\n });\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n [loadingKey]: false,\n },\n }));\n }\n };\n}\n\nconst formatReadState = (read: ReadResponse[]): ThreadReadState =>\n read.reduce<ThreadReadState>((state, userRead) => {\n state[userRead.user.id] = {\n user: userRead.user,\n lastReadMessageId: userRead.last_read_message_id,\n unreadMessageCount: userRead.unread_messages ?? 0,\n lastReadAt: new Date(userRead.last_read),\n };\n return state;\n }, {});\n\nconst repliesPaginationFromInitialThread = (thread: ThreadResponse): ThreadRepliesPagination => {\n const latestRepliesContainsAllReplies = thread.latest_replies.length === thread.reply_count;\n\n return {\n nextCursor: null,\n prevCursor: latestRepliesContainsAllReplies ? null : thread.latest_replies.at(0)?.id ?? null,\n isLoadingNext: false,\n isLoadingPrev: false,\n };\n};\n\nconst ownUnreadCountSelector = (currentUserId: string | undefined) => <\n SCG extends ExtendableGenerics = DefaultGenerics\n>(\n state: ThreadState<SCG>,\n) => (currentUserId && state.read[currentUserId]?.unreadMessageCount) || 0;\n","import {\n APIResponse,\n ModerationConfig,\n DefaultGenerics,\n ExtendableGenerics,\n GetConfigResponse,\n GetUserModerationReportResponse,\n MuteUserResponse,\n ReviewQueueFilters,\n ReviewQueuePaginationOptions,\n ReviewQueueResponse,\n ReviewQueueSort,\n UpsertConfigResponse,\n ModerationFlagOptions,\n ModerationMuteOptions,\n GetUserModerationReportOptions,\n SubmitActionOptions,\n QueryModerationConfigsFilters,\n QueryModerationConfigsSort,\n Pager,\n} from './types';\nimport { StreamChat } from './client';\nimport { normalizeQuerySort } from './utils';\n\nexport const MODERATION_ENTITY_TYPES = {\n user: 'stream:user',\n message: 'stream:chat:v1:message',\n};\n\n// Moderation class provides all the endpoints related to moderation v2.\nexport class Moderation<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n client: StreamChat<StreamChatGenerics>;\n\n constructor(client: StreamChat<StreamChatGenerics>) {\n this.client = client;\n }\n\n /**\n * Flag a user\n *\n * @param {string} flaggedUserID User ID to be flagged\n * @param {string} reason Reason for flagging the user\n * @param {Object} options Additional options for flagging the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target user\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flagUser(flaggedUserID: string, reason: string, options: ModerationFlagOptions = {}) {\n return this.flag(MODERATION_ENTITY_TYPES.user, flaggedUserID, '', reason, options);\n }\n\n /**\n * Flag a message\n *\n * @param {string} messageID Message ID to be flagged\n * @param {string} reason Reason for flagging the message\n * @param {Object} options Additional options for flagging the message\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target message\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flagMessage(messageID: string, reason: string, options: ModerationFlagOptions = {}) {\n return this.flag(MODERATION_ENTITY_TYPES.message, messageID, '', reason, options);\n }\n\n /**\n * Flag a user\n *\n * @param {string} entityType Entity type to be flagged\n * @param {string} entityId Entity ID to be flagged\n * @param {string} entityCreatorID User ID of the entity creator\n * @param {string} reason Reason for flagging the entity\n * @param {Object} options Additional options for flagging the entity\n * @param {string} options.user_id (For server side usage) User ID of the user who is flagging the target entity\n * @param {Object} options.moderation_payload Content to be flagged e.g., { texts: ['text1', 'text2'], images: ['image1', 'image2']}\n * @param {Object} options.custom Additional data to be stored with the flag\n * @returns\n */\n async flag(\n entityType: string,\n entityId: string,\n entityCreatorID: string,\n reason: string,\n options: ModerationFlagOptions = {},\n ) {\n return await this.client.post<{ item_id: string } & APIResponse>(this.client.baseURL + '/api/v2/moderation/flag', {\n entity_type: entityType,\n entity_id: entityId,\n entity_creator_id: entityCreatorID,\n reason,\n ...options,\n });\n }\n\n /**\n * Mute a user\n * @param {string} targetID User ID to be muted\n * @param {Object} options Additional options for muting the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is muting the target user\n * @param {number} options.timeout Timeout for the mute in minutes\n * @returns\n */\n async muteUser(targetID: string, options: ModerationMuteOptions = {}) {\n return await this.client.post<MuteUserResponse<StreamChatGenerics> & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/mute',\n {\n target_ids: [targetID],\n ...options,\n },\n );\n }\n\n /**\n * Unmute a user\n * @param {string} targetID User ID to be unmuted\n * @param {Object} options Additional options for unmuting the user\n * @param {string} options.user_id (For server side usage) User ID of the user who is unmuting the target user\n * @returns\n */\n async unmuteUser(\n targetID: string,\n options: {\n user_id?: string;\n },\n ) {\n return await this.client.post<{ item_id: string } & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/unmute',\n {\n target_ids: [targetID],\n ...options,\n },\n );\n }\n\n /**\n * Get moderation report for a user\n * @param {string} userID User ID for which moderation report is to be fetched\n * @param {Object} options Additional options for fetching the moderation report\n * @param {boolean} options.create_user_if_not_exists Create user if not exists\n * @param {boolean} options.include_user_blocks Include user blocks\n * @param {boolean} options.include_user_mutes Include user mutes\n */\n async getUserModerationReport(userID: string, options: GetUserModerationReportOptions = {}) {\n return await this.client.get<GetUserModerationReportResponse<StreamChatGenerics>>(\n this.client.baseURL + `/api/v2/moderation/user_report`,\n {\n user_id: userID,\n ...options,\n },\n );\n }\n\n /**\n * Query review queue\n * @param {Object} filterConditions Filter conditions for querying review queue\n * @param {Object} sort Sort conditions for querying review queue\n * @param {Object} options Pagination options for querying review queue\n */\n async queryReviewQueue(\n filterConditions: ReviewQueueFilters = {},\n sort: ReviewQueueSort = [],\n options: ReviewQueuePaginationOptions = {},\n ) {\n return await this.client.post<ReviewQueueResponse>(this.client.baseURL + '/api/v2/moderation/review_queue', {\n filter: filterConditions,\n sort: normalizeQuerySort(sort),\n ...options,\n });\n }\n\n /**\n * Upsert moderation config\n * @param {Object} config Moderation config to be upserted\n */\n async upsertConfig(config: ModerationConfig = {}) {\n return await this.client.post<UpsertConfigResponse>(this.client.baseURL + '/api/v2/moderation/config', config);\n }\n\n /**\n * Get moderation config\n * @param {string} key Key for which moderation config is to be fetched\n */\n async getConfig(key: string) {\n return await this.client.get<GetConfigResponse>(this.client.baseURL + '/api/v2/moderation/config/' + key);\n }\n\n async deleteConfig(key: string) {\n return await this.client.delete(this.client.baseURL + '/api/v2/moderation/config/' + key);\n }\n\n /**\n * Query moderation configs\n * @param {Object} filterConditions Filter conditions for querying moderation configs\n * @param {Object} sort Sort conditions for querying moderation configs\n * @param {Object} options Additional options for querying moderation configs\n */\n async queryConfigs(\n filterConditions: QueryModerationConfigsFilters,\n sort: QueryModerationConfigsSort,\n options: Pager = {},\n ) {\n return await this.client.post(this.client.baseURL + '/api/v2/moderation/configs', {\n filter: filterConditions,\n sort,\n ...options,\n });\n }\n\n async submitAction(actionType: string, itemID: string, options: SubmitActionOptions = {}) {\n return await this.client.post<{ item_id: string } & APIResponse>(\n this.client.baseURL + '/api/v2/moderation/submit_action',\n {\n action_type: actionType,\n item_id: itemID,\n ...options,\n },\n );\n }\n\n /**\n *\n * @param {string} entityType string Type of entity to be checked E.g., stream:user, stream:chat:v1:message, or any custom string\n * @param {string} entityID string ID of the entity to be checked. This is mainly for tracking purposes\n * @param {string} entityCreatorID string ID of the entity creator\n * @param {object} moderationPayload object Content to be checked for moderation. E.g., { texts: ['text1', 'text2'], images: ['image1', 'image2']}\n * @param {Array} moderationPayload.texts array Array of texts to be checked for moderation\n * @param {Array} moderationPayload.images array Array of images to be checked for moderation\n * @param {Array} moderationPayload.videos array Array of videos to be checked for moderation\n * @param configKey\n * @param options\n * @returns\n */\n async check(\n entityType: string,\n entityID: string,\n entityCreatorID: string,\n moderationPayload: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n custom?: Record<string, any>;\n images?: string[];\n texts?: string[];\n videos?: string[];\n },\n configKey: string,\n options?: {\n force_sync?: boolean;\n },\n ) {\n return await this.client.post(this.client.baseURL + `/api/v2/moderation/check`, {\n entity_type: entityType,\n entity_id: entityID,\n entity_creator_id: entityCreatorID,\n moderation_payload: moderationPayload,\n config_key: configKey,\n options,\n });\n }\n}\n","import { StateStore } from './store';\nimport { throttle } from './utils';\n\nimport type { StreamChat } from './client';\nimport type { Thread } from './thread';\nimport type { DefaultGenerics, Event, ExtendableGenerics, OwnUserResponse, QueryThreadsOptions } from './types';\n\nconst DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION = 1000;\nconst MAX_QUERY_THREADS_LIMIT = 25;\nexport const THREAD_MANAGER_INITIAL_STATE = {\n active: false,\n isThreadOrderStale: false,\n threads: [],\n unreadThreadCount: 0,\n unseenThreadIds: [],\n lastConnectionDropAt: null,\n pagination: {\n isLoading: false,\n isLoadingNext: false,\n nextCursor: null,\n },\n ready: false,\n};\n\nexport type ThreadManagerState<SCG extends ExtendableGenerics = DefaultGenerics> = {\n active: boolean;\n isThreadOrderStale: boolean;\n lastConnectionDropAt: Date | null;\n pagination: ThreadManagerPagination;\n ready: boolean;\n threads: Thread<SCG>[];\n unreadThreadCount: number;\n /**\n * List of threads that haven't been loaded in the list, but have received new messages\n * since the latest reload. Useful to display a banner prompting to reload the thread list.\n */\n unseenThreadIds: string[];\n};\n\nexport type ThreadManagerPagination = {\n isLoading: boolean;\n isLoadingNext: boolean;\n nextCursor: string | null;\n};\n\nexport class ThreadManager<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<ThreadManagerState<SCG>>;\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n private threadsByIdGetterCache: {\n threads: ThreadManagerState<SCG>['threads'];\n threadsById: Record<string, Thread<SCG> | undefined>;\n };\n\n constructor({ client }: { client: StreamChat<SCG> }) {\n this.client = client;\n this.state = new StateStore<ThreadManagerState<SCG>>(THREAD_MANAGER_INITIAL_STATE);\n\n this.threadsByIdGetterCache = { threads: [], threadsById: {} };\n }\n\n public get threadsById() {\n const { threads } = this.state.getLatestValue();\n\n if (threads === this.threadsByIdGetterCache.threads) {\n return this.threadsByIdGetterCache.threadsById;\n }\n\n const threadsById = threads.reduce<Record<string, Thread<SCG>>>((newThreadsById, thread) => {\n newThreadsById[thread.id] = thread;\n return newThreadsById;\n }, {});\n\n this.threadsByIdGetterCache.threads = threads;\n this.threadsByIdGetterCache.threadsById = threadsById;\n\n return threadsById;\n }\n\n public resetState = () => {\n this.state.next(THREAD_MANAGER_INITIAL_STATE);\n };\n\n public activate = () => {\n this.state.partialNext({ active: true });\n };\n\n public deactivate = () => {\n this.state.partialNext({ active: false });\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) return;\n\n this.unsubscribeFunctions.add(this.subscribeUnreadThreadsCountChange());\n this.unsubscribeFunctions.add(this.subscribeManageThreadSubscriptions());\n this.unsubscribeFunctions.add(this.subscribeReloadOnActivation());\n this.unsubscribeFunctions.add(this.subscribeNewReplies());\n this.unsubscribeFunctions.add(this.subscribeRecoverAfterConnectionDrop());\n this.unsubscribeFunctions.add(this.subscribeChannelDeleted());\n };\n\n private subscribeUnreadThreadsCountChange = () => {\n // initiate\n const { unread_threads: unreadThreadCount = 0 } = (this.client.user as OwnUserResponse<SCG>) ?? {};\n this.state.partialNext({ unreadThreadCount });\n\n const unsubscribeFunctions = [\n 'health.check',\n 'notification.mark_read',\n 'notification.thread_message_new',\n 'notification.channel_deleted',\n ].map(\n (eventType) =>\n this.client.on(eventType, (event) => {\n const { unread_threads: unreadThreadCount } = event.me ?? event;\n if (typeof unreadThreadCount === 'number') {\n this.state.partialNext({ unreadThreadCount });\n }\n }).unsubscribe,\n );\n\n return () => unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());\n };\n\n private subscribeChannelDeleted = () =>\n this.client.on('notification.channel_deleted', (event) => {\n const { cid } = event;\n const { threads } = this.state.getLatestValue();\n\n const newThreads = threads.filter((thread) => thread.channel.cid !== cid);\n this.state.partialNext({ threads: newThreads });\n }).unsubscribe;\n\n private subscribeManageThreadSubscriptions = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ threads: nextValue.threads }),\n ({ threads: nextThreads }, prev) => {\n const { threads: prevThreads = [] } = prev ?? {};\n // Thread instance was removed if there's no thread with the given id at all,\n // or it was replaced with a new instance\n const removedThreads = prevThreads.filter((thread) => thread !== this.threadsById[thread.id]);\n\n nextThreads.forEach((thread) => thread.registerSubscriptions());\n removedThreads.forEach((thread) => thread.unregisterSubscriptions());\n },\n );\n\n private subscribeReloadOnActivation = () =>\n this.state.subscribeWithSelector(\n (nextValue) => ({ active: nextValue.active }),\n ({ active }) => {\n if (active) this.reload();\n },\n );\n\n private subscribeNewReplies = () =>\n this.client.on('notification.thread_message_new', (event: Event<SCG>) => {\n const parentId = event.message?.parent_id;\n if (!parentId) return;\n\n const { unseenThreadIds, ready } = this.state.getLatestValue();\n if (!ready) return;\n\n if (this.threadsById[parentId]) {\n this.state.partialNext({ isThreadOrderStale: true });\n } else if (!unseenThreadIds.includes(parentId)) {\n this.state.partialNext({ unseenThreadIds: unseenThreadIds.concat(parentId) });\n }\n }).unsubscribe;\n\n private subscribeRecoverAfterConnectionDrop = () => {\n const unsubscribeConnectionDropped = this.client.on('connection.changed', (event) => {\n if (event.online === false) {\n this.state.next((current) =>\n current.lastConnectionDropAt\n ? current\n : {\n ...current,\n lastConnectionDropAt: new Date(),\n },\n );\n }\n }).unsubscribe;\n\n const throttledHandleConnectionRecovered = throttle(\n () => {\n const { lastConnectionDropAt } = this.state.getLatestValue();\n if (!lastConnectionDropAt) return;\n this.reload({ force: true });\n },\n DEFAULT_CONNECTION_RECOVERY_THROTTLE_DURATION,\n { trailing: true },\n );\n\n const unsubscribeConnectionRecovered = this.client.on('connection.recovered', throttledHandleConnectionRecovered)\n .unsubscribe;\n\n return () => {\n unsubscribeConnectionDropped();\n unsubscribeConnectionRecovered();\n };\n };\n\n public unregisterSubscriptions = () => {\n this.state.getLatestValue().threads.forEach((thread) => thread.unregisterSubscriptions());\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public reload = async ({ force = false } = {}) => {\n const { threads, unseenThreadIds, isThreadOrderStale, pagination, ready } = this.state.getLatestValue();\n if (pagination.isLoading) return;\n if (!force && ready && !unseenThreadIds.length && !isThreadOrderStale) return;\n const limit = threads.length + unseenThreadIds.length;\n\n try {\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoading: true,\n },\n }));\n\n const response = await this.queryThreads({\n limit: Math.min(limit, MAX_QUERY_THREADS_LIMIT) || MAX_QUERY_THREADS_LIMIT,\n });\n\n const currentThreads = this.threadsById;\n const nextThreads: Thread<SCG>[] = [];\n\n for (const incomingThread of response.threads) {\n const existingThread = currentThreads[incomingThread.id];\n\n if (existingThread) {\n // Reuse thread instances if possible\n nextThreads.push(existingThread);\n if (existingThread.hasStaleState) {\n existingThread.hydrateState(incomingThread);\n }\n } else {\n nextThreads.push(incomingThread);\n }\n }\n\n this.state.next((current) => ({\n ...current,\n threads: nextThreads,\n unseenThreadIds: [],\n isThreadOrderStale: false,\n pagination: {\n ...current.pagination,\n isLoading: false,\n nextCursor: response.next ?? null,\n },\n ready: true,\n }));\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoading: false,\n },\n }));\n }\n };\n\n public queryThreads = (options: QueryThreadsOptions = {}) => {\n return this.client.queryThreads({\n limit: 25,\n participant_limit: 10,\n reply_limit: 10,\n watch: true,\n ...options,\n });\n };\n\n public loadNextPage = async (options: Omit<QueryThreadsOptions, 'next'> = {}) => {\n const { pagination } = this.state.getLatestValue();\n\n if (pagination.isLoadingNext || !pagination.nextCursor) return;\n\n try {\n this.state.partialNext({ pagination: { ...pagination, isLoadingNext: true } });\n\n const response = await this.queryThreads({\n ...options,\n next: pagination.nextCursor,\n });\n\n this.state.next((current) => ({\n ...current,\n threads: response.threads.length ? current.threads.concat(response.threads) : current.threads,\n pagination: {\n ...current.pagination,\n nextCursor: response.next ?? null,\n isLoadingNext: false,\n },\n }));\n } catch (error) {\n this.client.logger('error', (error as Error).message);\n this.state.next((current) => ({\n ...current,\n pagination: {\n ...current.pagination,\n isLoadingNext: false,\n },\n }));\n }\n };\n}\n","import { StateStore } from './store';\nimport type { StreamChat } from './client';\nimport type {\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n PartialPollUpdate,\n PollAnswer,\n PollData,\n PollEnrichData,\n PollOptionData,\n PollResponse,\n PollVote,\n QueryVotesFilters,\n QueryVotesOptions,\n VoteSort,\n} from './types';\n\ntype PollEvent<SCG extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n created_at: string;\n poll: PollResponse<SCG>;\n};\n\ntype PollUpdatedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollEvent<SCG> & {\n type: 'poll.updated';\n};\n\ntype PollClosedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollEvent<SCG> & {\n type: 'poll.closed';\n};\n\ntype PollVoteEvent<SCG extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n created_at: string;\n poll: PollResponse<SCG>;\n poll_vote: PollVote<SCG> | PollAnswer<SCG>;\n};\n\ntype PollVoteCastedEvent<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_casted';\n};\n\ntype PollVoteCastedChanged<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_removed';\n};\n\ntype PollVoteCastedRemoved<SCG extends ExtendableGenerics = DefaultGenerics> = PollVoteEvent<SCG> & {\n type: 'poll.vote_removed';\n};\n\nconst isPollUpdatedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollUpdatedEvent<SCG> => e.type === 'poll.updated';\nconst isPollClosedEventEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollClosedEvent<SCG> => e.type === 'poll.closed';\nconst isPollVoteCastedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedEvent<SCG> => e.type === 'poll.vote_casted';\nconst isPollVoteChangedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedChanged<SCG> => e.type === 'poll.vote_changed';\nconst isPollVoteRemovedEvent = <SCG extends ExtendableGenerics = DefaultGenerics>(\n e: Event<SCG>,\n): e is PollVoteCastedRemoved<SCG> => e.type === 'poll.vote_removed';\n\nexport const isVoteAnswer = <SCG extends ExtendableGenerics = DefaultGenerics>(\n vote: PollVote<SCG> | PollAnswer<SCG>,\n): vote is PollAnswer<SCG> => !!(vote as PollAnswer<SCG>)?.answer_text;\n\nexport type PollAnswersQueryParams = {\n filter?: QueryVotesFilters;\n options?: QueryVotesOptions;\n sort?: VoteSort;\n};\n\nexport type PollOptionVotesQueryParams = {\n filter: { option_id: string } & QueryVotesFilters;\n options?: QueryVotesOptions;\n sort?: VoteSort;\n};\n\ntype OptionId = string;\n\nexport type PollState<SCG extends ExtendableGenerics = DefaultGenerics> = SCG['pollType'] &\n Omit<PollResponse<SCG>, 'own_votes' | 'id'> & {\n lastActivityAt: Date; // todo: would be ideal to get this from the BE\n maxVotedOptionIds: OptionId[];\n ownVotesByOptionId: Record<OptionId, PollVote<SCG>>;\n ownAnswer?: PollAnswer; // each user can have only one answer\n };\n\ntype PollInitOptions<SCG extends ExtendableGenerics = DefaultGenerics> = {\n client: StreamChat<SCG>;\n poll: PollResponse<SCG>;\n};\n\nexport class Poll<SCG extends ExtendableGenerics = DefaultGenerics> {\n public readonly state: StateStore<PollState<SCG>>;\n public id: string;\n private client: StreamChat<SCG>;\n private unsubscribeFunctions: Set<() => void> = new Set();\n\n constructor({ client, poll }: PollInitOptions<SCG>) {\n this.client = client;\n this.id = poll.id;\n\n this.state = new StateStore<PollState<SCG>>(this.getInitialStateFromPollResponse(poll));\n }\n\n private getInitialStateFromPollResponse = (poll: PollInitOptions<SCG>['poll']) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { own_votes, id, ...pollResponseForState } = poll;\n const { ownAnswer, ownVotes } = own_votes?.reduce<{ ownVotes: PollVote<SCG>[]; ownAnswer?: PollAnswer }>(\n (acc, voteOrAnswer) => {\n if (isVoteAnswer(voteOrAnswer)) {\n acc.ownAnswer = voteOrAnswer;\n } else {\n acc.ownVotes.push(voteOrAnswer);\n }\n return acc;\n },\n { ownVotes: [] },\n ) ?? { ownVotes: [] };\n\n return {\n ...pollResponseForState,\n lastActivityAt: new Date(),\n maxVotedOptionIds: getMaxVotedOptionIds(\n pollResponseForState.vote_counts_by_option as PollResponse<SCG>['vote_counts_by_option'],\n ),\n ownAnswer,\n ownVotesByOptionId: getOwnVotesByOptionId(ownVotes),\n };\n };\n\n public reinitializeState = (poll: PollInitOptions<SCG>['poll']) => {\n this.state.partialNext(this.getInitialStateFromPollResponse(poll));\n };\n\n get data(): PollState<SCG> {\n return this.state.getLatestValue();\n }\n\n public handlePollUpdated = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollUpdatedEvent(event)) return;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { id, ...pollData } = extractPollData(event.poll);\n // @ts-ignore\n this.state.partialNext({ ...pollData, lastActivityAt: new Date(event.created_at) });\n };\n\n public handlePollClosed = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollClosedEventEvent(event)) return;\n // @ts-ignore\n this.state.partialNext({ is_closed: true, lastActivityAt: new Date(event.created_at) });\n };\n\n public handleVoteCasted = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteCastedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n const ownVotesByOptionId = currentState.ownVotesByOptionId;\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isOwnVote) {\n if (isVoteAnswer(event.poll_vote)) {\n ownAnswer = event.poll_vote;\n } else if (event.poll_vote.option_id) {\n ownVotesByOptionId[event.poll_vote.option_id] = event.poll_vote;\n }\n }\n\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers];\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n public handleVoteChanged = (event: Event<SCG>) => {\n // this event is triggered only when event.poll.enforce_unique_vote === true\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteChangedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n let ownVotesByOptionId = currentState.ownVotesByOptionId;\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isOwnVote) {\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers.filter((answer) => answer.id !== event.poll_vote.id)];\n ownAnswer = event.poll_vote;\n } else if (event.poll_vote.option_id) {\n if (event.poll.enforce_unique_votes) {\n ownVotesByOptionId = { [event.poll_vote.option_id]: event.poll_vote };\n } else {\n ownVotesByOptionId = Object.entries(ownVotesByOptionId).reduce<Record<OptionId, PollVote<SCG>>>(\n (acc, [optionId, vote]) => {\n if (optionId !== event.poll_vote.option_id && vote.id === event.poll_vote.id) {\n return acc;\n }\n acc[optionId] = vote;\n return acc;\n },\n {},\n );\n ownVotesByOptionId[event.poll_vote.option_id] = event.poll_vote;\n }\n\n if (ownAnswer?.id === event.poll_vote.id) {\n ownAnswer = undefined;\n }\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n } else if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = [event.poll_vote, ...latestAnswers];\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n public handleVoteRemoved = (event: Event<SCG>) => {\n if (event.poll?.id && event.poll.id !== this.id) return;\n if (!isPollVoteRemovedEvent(event)) return;\n const currentState = this.data;\n const isOwnVote = event.poll_vote.user_id === this.client.userID;\n let latestAnswers = [...(currentState.latest_answers as PollAnswer[])];\n let ownAnswer = currentState.ownAnswer;\n const ownVotesByOptionId = { ...currentState.ownVotesByOptionId };\n let maxVotedOptionIds = currentState.maxVotedOptionIds;\n\n if (isVoteAnswer(event.poll_vote)) {\n latestAnswers = latestAnswers.filter((answer) => answer.id !== event.poll_vote.id);\n if (isOwnVote) {\n ownAnswer = undefined;\n }\n } else {\n maxVotedOptionIds = getMaxVotedOptionIds(event.poll.vote_counts_by_option);\n if (isOwnVote && event.poll_vote.option_id) {\n delete ownVotesByOptionId[event.poll_vote.option_id];\n }\n }\n\n const pollEnrichData = extractPollEnrichedData(event.poll);\n // @ts-ignore\n this.state.partialNext({\n ...pollEnrichData,\n latest_answers: latestAnswers,\n lastActivityAt: new Date(event.created_at),\n ownAnswer,\n ownVotesByOptionId,\n maxVotedOptionIds,\n });\n };\n\n query = async (id: string) => {\n const { poll } = await this.client.getPoll(id);\n // @ts-ignore\n this.state.partialNext({ ...poll, lastActivityAt: new Date() });\n return poll;\n };\n\n update = async (data: Exclude<PollData<SCG>, 'id'>) => {\n return await this.client.updatePoll({ ...data, id: this.id });\n };\n\n partialUpdate = async (partialPollObject: PartialPollUpdate<SCG>) => {\n return await this.client.partialUpdatePoll(this.id as string, partialPollObject);\n };\n\n close = async () => {\n return await this.client.closePoll(this.id as string);\n };\n\n delete = async () => {\n return await this.client.deletePoll(this.id as string);\n };\n\n createOption = async (option: PollOptionData) => {\n return await this.client.createPollOption(this.id as string, option);\n };\n\n updateOption = async (option: PollOptionData) => {\n return await this.client.updatePollOption(this.id as string, option);\n };\n\n deleteOption = async (optionId: string) => {\n return await this.client.deletePollOption(this.id as string, optionId);\n };\n\n castVote = async (optionId: string, messageId: string) => {\n const { max_votes_allowed, ownVotesByOptionId } = this.data;\n\n const reachedVoteLimit = max_votes_allowed && max_votes_allowed === Object.keys(ownVotesByOptionId).length;\n\n if (reachedVoteLimit) {\n let oldestVote = Object.values(ownVotesByOptionId)[0];\n Object.values(ownVotesByOptionId)\n .slice(1)\n .forEach((vote) => {\n if (!oldestVote?.created_at || new Date(vote.created_at) < new Date(oldestVote.created_at)) {\n oldestVote = vote;\n }\n });\n if (oldestVote?.id) {\n await this.removeVote(oldestVote.id, messageId);\n }\n }\n return await this.client.castPollVote(messageId, this.id as string, { option_id: optionId });\n };\n\n removeVote = async (voteId: string, messageId: string) => {\n return await this.client.removePollVote(messageId, this.id as string, voteId);\n };\n\n addAnswer = async (answerText: string, messageId: string) => {\n return await this.client.addPollAnswer(messageId, this.id as string, answerText);\n };\n\n removeAnswer = async (answerId: string, messageId: string) => {\n return await this.client.removePollVote(messageId, this.id as string, answerId);\n };\n\n queryAnswers = async (params: PollAnswersQueryParams) => {\n return await this.client.queryPollAnswers(this.id as string, params.filter, params.sort, params.options);\n };\n\n queryOptionVotes = async (params: PollOptionVotesQueryParams) => {\n return await this.client.queryPollVotes(this.id as string, params.filter, params.sort, params.options);\n };\n}\n\nfunction getMaxVotedOptionIds(voteCountsByOption: PollResponse['vote_counts_by_option']) {\n let maxVotes = 0;\n let winningOptions: string[] = [];\n for (const [id, count] of Object.entries(voteCountsByOption ?? {})) {\n if (count > maxVotes) {\n winningOptions = [id];\n maxVotes = count;\n } else if (count === maxVotes) {\n winningOptions.push(id);\n }\n }\n return winningOptions;\n}\n\nfunction getOwnVotesByOptionId<SCG extends ExtendableGenerics = DefaultGenerics>(ownVotes: PollVote<SCG>[]) {\n return !ownVotes\n ? ({} as Record<OptionId, PollVote<SCG>>)\n : ownVotes.reduce<Record<OptionId, PollVote<SCG>>>((acc, vote) => {\n if (isVoteAnswer(vote) || !vote.option_id) return acc;\n acc[vote.option_id] = vote;\n return acc;\n }, {});\n}\n\nexport function extractPollData<SCG extends ExtendableGenerics = DefaultGenerics>(\n pollResponse: PollResponse<SCG>,\n): PollData<SCG> {\n return {\n allow_answers: pollResponse.allow_answers,\n allow_user_suggested_options: pollResponse.allow_user_suggested_options,\n description: pollResponse.description,\n enforce_unique_vote: pollResponse.enforce_unique_vote,\n id: pollResponse.id,\n is_closed: pollResponse.is_closed,\n max_votes_allowed: pollResponse.max_votes_allowed,\n name: pollResponse.name,\n options: pollResponse.options,\n voting_visibility: pollResponse.voting_visibility,\n };\n}\n\nexport function extractPollEnrichedData<SCG extends ExtendableGenerics = DefaultGenerics>(\n pollResponse: PollResponse<SCG>,\n): Omit<PollEnrichData<SCG>, 'own_votes' | 'latest_answers'> {\n return {\n answers_count: pollResponse.answers_count,\n latest_votes_by_option: pollResponse.latest_votes_by_option,\n vote_count: pollResponse.vote_count,\n vote_counts_by_option: pollResponse.vote_counts_by_option,\n };\n}\n","import type { StreamChat } from './client';\nimport type {\n CreatePollData,\n DefaultGenerics,\n ExtendableGenerics,\n PollResponse,\n PollSort,\n QueryPollsFilters,\n QueryPollsOptions,\n} from './types';\nimport { Poll } from './poll';\nimport { FormatMessageResponse } from './types';\nimport { formatMessage } from './utils';\n\nexport class PollManager<SCG extends ExtendableGenerics = DefaultGenerics> {\n private client: StreamChat<SCG>;\n // The pollCache contains only polls that have been created and sent as messages\n // (i.e only polls that are coupled with a message, can be voted on and require a\n // reactive state). It shall work as a basic look-up table for our SDK to be able\n // to quickly consume poll state that will be reactive even without the polls being\n // rendered within the UI.\n private pollCache = new Map<string, Poll<SCG>>();\n private unsubscribeFunctions: Set<() => void> = new Set();\n\n constructor({ client }: { client: StreamChat<SCG> }) {\n this.client = client;\n }\n\n get data(): Map<string, Poll<SCG>> {\n return this.pollCache;\n }\n\n public fromState = (id: string) => {\n return this.pollCache.get(id);\n };\n\n public registerSubscriptions = () => {\n if (this.unsubscribeFunctions.size) {\n // Already listening for events and changes\n return;\n }\n\n this.unsubscribeFunctions.add(this.subscribeMessageNew());\n this.unsubscribeFunctions.add(this.subscribePollUpdated());\n this.unsubscribeFunctions.add(this.subscribePollClosed());\n this.unsubscribeFunctions.add(this.subscribeVoteCasted());\n this.unsubscribeFunctions.add(this.subscribeVoteChanged());\n this.unsubscribeFunctions.add(this.subscribeVoteRemoved());\n };\n\n public unregisterSubscriptions = () => {\n this.unsubscribeFunctions.forEach((cleanupFunction) => cleanupFunction());\n this.unsubscribeFunctions.clear();\n };\n\n public createPoll = async (poll: CreatePollData<SCG>) => {\n const { poll: createdPoll } = await this.client.createPoll(poll);\n\n return new Poll({ client: this.client, poll: createdPoll });\n };\n\n public getPoll = async (id: string) => {\n const cachedPoll = this.fromState(id);\n\n // optimistically return the cached poll if it exists and update in the background\n if (cachedPoll) {\n this.client.getPoll(id).then(({ poll }) => this.setOrOverwriteInCache(poll, true));\n return cachedPoll;\n }\n // fetch it, write to the cache and return otherwise\n const { poll } = await this.client.getPoll(id);\n\n this.setOrOverwriteInCache(poll);\n\n return this.fromState(id);\n };\n\n public queryPolls = async (filter: QueryPollsFilters, sort: PollSort = [], options: QueryPollsOptions = {}) => {\n const { polls, next } = await this.client.queryPolls(filter, sort, options);\n\n const pollInstances = polls.map((poll) => {\n this.setOrOverwriteInCache(poll, true);\n\n return this.fromState(poll.id);\n });\n\n return {\n polls: pollInstances,\n next,\n };\n };\n\n public hydratePollCache = (messages: FormatMessageResponse<SCG>[], overwriteState?: boolean) => {\n for (const message of messages) {\n if (!message.poll) {\n continue;\n }\n const pollResponse = message.poll as PollResponse<SCG>;\n this.setOrOverwriteInCache(pollResponse, overwriteState);\n }\n };\n\n private setOrOverwriteInCache = (pollResponse: PollResponse<SCG>, overwriteState?: boolean) => {\n const pollFromCache = this.fromState(pollResponse.id);\n if (!pollFromCache) {\n const poll = new Poll<SCG>({ client: this.client, poll: pollResponse });\n this.pollCache.set(poll.id, poll);\n } else if (overwriteState) {\n pollFromCache.reinitializeState(pollResponse);\n }\n };\n\n private subscribePollUpdated = () => {\n return this.client.on('poll.updated', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handlePollUpdated(event);\n }\n }).unsubscribe;\n };\n\n private subscribePollClosed = () => {\n return this.client.on('poll.closed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handlePollClosed(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteCasted = () => {\n return this.client.on('poll.vote_casted', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteCasted(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteChanged = () => {\n return this.client.on('poll.vote_changed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteChanged(event);\n }\n }).unsubscribe;\n };\n\n private subscribeVoteRemoved = () => {\n return this.client.on('poll.vote_removed', (event) => {\n if (event.poll?.id) {\n this.fromState(event.poll.id)?.handleVoteRemoved(event);\n }\n }).unsubscribe;\n };\n\n private subscribeMessageNew = () => {\n return this.client.on('message.new', (event) => {\n const { message } = event;\n if (message) {\n const formattedMessage = formatMessage(message);\n this.hydratePollCache([formattedMessage]);\n }\n }).unsubscribe;\n };\n}\n","/* eslint no-unused-vars: \"off\" */\n/* global process */\n\nimport axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport https from 'https';\nimport WebSocket from 'isomorphic-ws';\n\nimport { Channel } from './channel';\nimport { ClientState } from './client_state';\nimport { StableWSConnection } from './connection';\nimport { CheckSignature, DevToken, JWTUserToken } from './signing';\nimport { TokenManager } from './token_manager';\nimport { WSConnectionFallback } from './connection_fallback';\nimport { Campaign } from './campaign';\nimport { Segment } from './segment';\nimport { isErrorResponse, isWSFailure } from './errors';\nimport {\n addFileToFormData,\n axiosParamsSerializer,\n chatCodes,\n isFunction,\n isOnline,\n isOwnUserBaseProperty,\n messageSetPagination,\n normalizeQuerySort,\n randomId,\n retryInterval,\n sleep,\n} from './utils';\n\nimport {\n APIErrorResponse,\n APIResponse,\n AppSettings,\n AppSettingsAPIResponse,\n BannedUsersFilters,\n BannedUsersPaginationOptions,\n BannedUsersResponse,\n BannedUsersSort,\n BanUserOptions,\n BaseDeviceFields,\n BlockList,\n BlockListResponse,\n BlockUserAPIResponse,\n CampaignData,\n CampaignFilters,\n CampaignQueryOptions,\n CampaignResponse,\n CampaignSort,\n CastVoteAPIResponse,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelMute,\n ChannelOptions,\n ChannelResponse,\n ChannelSort,\n ChannelStateOptions,\n CheckPushResponse,\n CheckSNSResponse,\n CheckSQSResponse,\n Configs,\n ConnectAPIResponse,\n CreateChannelOptions,\n CreateChannelResponse,\n CreateCommandOptions,\n CreateCommandResponse,\n CreateImportOptions,\n CreateImportResponse,\n CreateImportURLResponse,\n CreatePollAPIResponse,\n CreatePollData,\n CreatePollOptionAPIResponse,\n CustomPermissionOptions,\n DeactivateUsersOptions,\n DefaultGenerics,\n DeleteChannelsResponse,\n DeleteCommandResponse,\n DeleteUserOptions,\n Device,\n EndpointName,\n ErrorFromResponse,\n Event,\n EventHandler,\n ExportChannelOptions,\n ExportChannelRequest,\n ExportChannelResponse,\n ExportChannelStatusResponse,\n ExportUsersRequest,\n ExportUsersResponse,\n ExtendableGenerics,\n FlagMessageResponse,\n FlagReportsFilters,\n FlagReportsPaginationOptions,\n FlagReportsResponse,\n FlagsFilters,\n FlagsPaginationOptions,\n FlagsResponse,\n FlagUserResponse,\n GetBlockedUsersAPIResponse,\n GetCallTokenResponse,\n GetChannelTypeResponse,\n GetCommandResponse,\n GetImportResponse,\n GetMessageAPIResponse,\n GetMessageOptions,\n GetPollAPIResponse,\n GetPollOptionAPIResponse,\n GetRateLimitsResponse,\n GetThreadAPIResponse,\n GetThreadOptions,\n GetUnreadCountAPIResponse,\n GetUnreadCountBatchAPIResponse,\n ListChannelResponse,\n ListCommandsResponse,\n ListImportsPaginationOptions,\n ListImportsResponse,\n Logger,\n MarkChannelsReadOptions,\n Message,\n MessageFilters,\n MessageFlagsFilters,\n MessageFlagsPaginationOptions,\n MessageFlagsResponse,\n MessageResponse,\n Mute,\n MuteUserOptions,\n MuteUserResponse,\n OGAttachment,\n OwnUserResponse,\n PartialMessageUpdate,\n PartialPollUpdate,\n PartialThreadUpdate,\n PartialUserUpdate,\n PermissionAPIResponse,\n PermissionsAPIResponse,\n PollAnswersAPIResponse,\n PollData,\n PollOptionData,\n PollSort,\n PollVote,\n PollVoteData,\n PollVotesAPIResponse,\n PushProvider,\n PushProviderConfig,\n PushProviderID,\n PushProviderListResponse,\n PushProviderUpsertResponse,\n QueryChannelsAPIResponse,\n QueryMessageHistoryFilters,\n QueryMessageHistoryOptions,\n QueryMessageHistoryResponse,\n QueryMessageHistorySort,\n QueryPollsFilters,\n QueryPollsOptions,\n QueryPollsResponse,\n QueryReactionsAPIResponse,\n QueryReactionsOptions,\n QuerySegmentsOptions,\n QuerySegmentTargetsFilter,\n QueryThreadsAPIResponse,\n QueryThreadsOptions,\n QueryVotesFilters,\n QueryVotesOptions,\n ReactionFilters,\n ReactionResponse,\n ReactionSort,\n ReactivateUserOptions,\n ReactivateUsersOptions,\n ReservedMessageFields,\n ReviewFlagReportOptions,\n ReviewFlagReportResponse,\n SearchAPIResponse,\n SearchMessageSortBase,\n SearchOptions,\n SearchPayload,\n SegmentData,\n SegmentResponse,\n SegmentTargetsResponse,\n SegmentType,\n SendFileAPIResponse,\n SortParam,\n StreamChatOptions,\n SyncOptions,\n SyncResponse,\n TaskResponse,\n TaskStatus,\n TestPushDataInput,\n TestSNSDataInput,\n TestSQSDataInput,\n TokenOrProvider,\n UnBanUserOptions,\n UpdateChannelOptions,\n UpdateChannelResponse,\n UpdateCommandOptions,\n UpdateCommandResponse,\n UpdatedMessage,\n UpdateMessageAPIResponse,\n UpdateMessageOptions,\n UpdatePollAPIResponse,\n UpdatePollOptionAPIResponse,\n UpdateSegmentData,\n UserCustomEvent,\n UserFilters,\n UserOptions,\n UserResponse,\n UserSort,\n VoteSort,\n} from './types';\nimport { InsightMetrics, postInsights } from './insights';\nimport { Thread } from './thread';\nimport { Moderation } from './moderation';\nimport { ThreadManager } from './thread_manager';\nimport { DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE } from './constants';\nimport { PollManager } from './poll_manager';\n\nfunction isString(x: unknown): x is string {\n return typeof x === 'string' || x instanceof String;\n}\n\nexport class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n private static _instance?: unknown | StreamChat; // type is undefined|StreamChat, unknown is due to TS limitations with statics\n\n _user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>;\n activeChannels: {\n [key: string]: Channel<StreamChatGenerics>;\n };\n threads: ThreadManager<StreamChatGenerics>;\n polls: PollManager<StreamChatGenerics>;\n anonymous: boolean;\n persistUserOnConnectionFailure?: boolean;\n axiosInstance: AxiosInstance;\n baseURL?: string;\n browser: boolean;\n cleaningIntervalRef?: NodeJS.Timeout;\n clientID?: string;\n configs: Configs<StreamChatGenerics>;\n key: string;\n listeners: Record<string, Array<(event: Event<StreamChatGenerics>) => void>>;\n logger: Logger;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n moderation: Moderation<StreamChatGenerics>;\n mutedChannels: ChannelMute<StreamChatGenerics>[];\n mutedUsers: Mute<StreamChatGenerics>[];\n node: boolean;\n options: StreamChatOptions;\n secret?: string;\n setUserPromise: ConnectAPIResponse<StreamChatGenerics> | null;\n state: ClientState<StreamChatGenerics>;\n tokenManager: TokenManager<StreamChatGenerics>;\n user?: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>;\n userAgent?: string;\n userID?: string;\n wsBaseURL?: string;\n wsConnection: StableWSConnection<StreamChatGenerics> | null;\n wsFallback?: WSConnectionFallback<StreamChatGenerics>;\n wsPromise: ConnectAPIResponse<StreamChatGenerics> | null;\n consecutiveFailures: number;\n insightMetrics: InsightMetrics;\n defaultWSTimeoutWithFallback: number;\n defaultWSTimeout: number;\n private nextRequestAbortController: AbortController | null = null;\n\n /**\n * Initialize a client\n *\n * **Only use constructor for advanced usages. It is strongly advised to use `StreamChat.getInstance()` instead of `new StreamChat()` to reduce integration issues due to multiple WebSocket connections**\n * @param {string} key - the api key\n * @param {string} [secret] - the api secret\n * @param {StreamChatOptions} [options] - additional options, here you can pass custom options to axios instance\n * @param {boolean} [options.browser] - enforce the client to be in browser mode\n * @param {boolean} [options.warmUp] - default to false, if true, client will open a connection as soon as possible to speed up following requests\n * @param {Logger} [options.Logger] - custom logger\n * @param {number} [options.timeout] - default to 3000\n * @param {httpsAgent} [options.httpsAgent] - custom httpsAgent, in node it's default to https.agent()\n * @example <caption>initialize the client in user mode</caption>\n * new StreamChat('api_key')\n * @example <caption>initialize the client in user mode with options</caption>\n * new StreamChat('api_key', { warmUp:true, timeout:5000 })\n * @example <caption>secret is optional and only used in server side mode</caption>\n * new StreamChat('api_key', \"secret\", { httpsAgent: customAgent })\n */\n constructor(key: string, options?: StreamChatOptions);\n constructor(key: string, secret?: string, options?: StreamChatOptions);\n constructor(key: string, secretOrOptions?: StreamChatOptions | string, options?: StreamChatOptions) {\n // set the key\n this.key = key;\n this.listeners = {};\n this.state = new ClientState<StreamChatGenerics>();\n // a list of channels to hide ws events from\n this.mutedChannels = [];\n this.mutedUsers = [];\n\n this.moderation = new Moderation(this);\n\n // set the secret\n if (secretOrOptions && isString(secretOrOptions)) {\n this.secret = secretOrOptions;\n }\n\n // set the options... and figure out defaults...\n const inputOptions = options ? options : secretOrOptions && !isString(secretOrOptions) ? secretOrOptions : {};\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n\n this.options = {\n timeout: 3000,\n withCredentials: false, // making sure cookies are not sent\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n\n this.axiosInstance = axios.create(this.options);\n\n this.setBaseURL(this.options.baseURL || 'https://chat.stream-io-api.com');\n\n if (typeof process !== 'undefined' && 'env' in process && process.env.STREAM_LOCAL_TEST_RUN) {\n this.setBaseURL('http://localhost:3030');\n }\n\n if (typeof process !== 'undefined' && 'env' in process && process.env.STREAM_LOCAL_TEST_HOST) {\n this.setBaseURL('http://' + process.env.STREAM_LOCAL_TEST_HOST);\n }\n\n // WS connection is initialized when setUser is called\n this.wsConnection = null;\n this.wsPromise = null;\n this.setUserPromise = null;\n // keeps a reference to all the channels that are in use\n this.activeChannels = {};\n\n // mapping between channel groups and configs\n this.configs = {};\n this.anonymous = false;\n this.persistUserOnConnectionFailure = this.options?.persistUserOnConnectionFailure;\n\n // If its a server-side client, then lets initialize the tokenManager, since token will be\n // generated from secret.\n this.tokenManager = new TokenManager(this.secret);\n this.consecutiveFailures = 0;\n this.insightMetrics = new InsightMetrics();\n\n this.defaultWSTimeoutWithFallback = 6 * 1000;\n this.defaultWSTimeout = 15 * 1000;\n\n this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;\n\n /**\n * logger function should accept 3 parameters:\n * @param logLevel string\n * @param message string\n * @param extraData object\n *\n * e.g.,\n * const client = new StreamChat('api_key', {}, {\n * \t\tlogger = (logLevel, message, extraData) => {\n * \t\t\tconsole.log(message);\n * \t\t}\n * })\n *\n * extraData contains tags array attached to log message. Tags can have one/many of following values:\n * 1. api\n * 2. api_request\n * 3. api_response\n * 4. client\n * 5. channel\n * 6. connection\n * 7. event\n *\n * It may also contains some extra data, some examples have been mentioned below:\n * 1. {\n * \t\ttags: ['api', 'api_request', 'client'],\n * \t\turl: string,\n * \t\tpayload: object,\n * \t\tconfig: object\n * }\n * 2. {\n * \t\ttags: ['api', 'api_response', 'client'],\n * \t\turl: string,\n * \t\tresponse: object\n * }\n * 3. {\n * \t\ttags: ['api', 'api_response', 'client'],\n * \t\turl: string,\n * \t\terror: object\n * }\n * 4. {\n * \t\ttags: ['event', 'client'],\n * \t\tevent: object\n * }\n * 5. {\n * \t\ttags: ['channel'],\n * \t\tchannel: object\n * }\n */\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;\n this.threads = new ThreadManager({ client: this });\n this.polls = new PollManager({ client: this });\n }\n\n /**\n * Get a client instance\n *\n * This function always returns the same Client instance to avoid issues raised by multiple Client and WS connections\n *\n * **After the first call, the client configuration will not change if the key or options parameters change**\n *\n * @param {string} key - the api key\n * @param {string} [secret] - the api secret\n * @param {StreamChatOptions} [options] - additional options, here you can pass custom options to axios instance\n * @param {boolean} [options.browser] - enforce the client to be in browser mode\n * @param {boolean} [options.warmUp] - default to false, if true, client will open a connection as soon as possible to speed up following requests\n * @param {Logger} [options.Logger] - custom logger\n * @param {number} [options.timeout] - default to 3000\n * @param {httpsAgent} [options.httpsAgent] - custom httpsAgent, in node it's default to https.agent()\n * @example <caption>initialize the client in user mode</caption>\n * StreamChat.getInstance('api_key')\n * @example <caption>initialize the client in user mode with options</caption>\n * StreamChat.getInstance('api_key', { timeout:5000 })\n * @example <caption>secret is optional and only used in server side mode</caption>\n * StreamChat.getInstance('api_key', \"secret\", { httpsAgent: customAgent })\n */\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics>;\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n secret?: string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics>;\n public static getInstance<StreamChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n secretOrOptions?: StreamChatOptions | string,\n options?: StreamChatOptions,\n ): StreamChat<StreamChatGenerics> {\n if (!StreamChat._instance) {\n if (typeof secretOrOptions === 'string') {\n StreamChat._instance = new StreamChat<StreamChatGenerics>(key, secretOrOptions, options);\n } else {\n StreamChat._instance = new StreamChat<StreamChatGenerics>(key, secretOrOptions);\n }\n }\n\n return StreamChat._instance as StreamChat<StreamChatGenerics>;\n }\n\n devToken(userID: string) {\n return DevToken(userID);\n }\n\n getAuthType() {\n return this.anonymous ? 'anonymous' : 'jwt';\n }\n\n setBaseURL(baseURL: string) {\n this.baseURL = baseURL;\n this.wsBaseURL = this.baseURL.replace('http', 'ws').replace(':3030', ':8800');\n }\n\n _getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;\n\n _hasConnectionID = () => Boolean(this._getConnectionID());\n\n /**\n * connectUser - Set the current user and open a WebSocket connection\n *\n * @param {OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n * @param {TokenOrProvider} userTokenOrProvider Token or provider\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n connectUser = async (\n user: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>,\n userTokenOrProvider: TokenOrProvider,\n ) => {\n if (!user.id) {\n throw new Error('The \"id\" field on the user is missing');\n }\n\n /**\n * Calling connectUser multiple times is potentially the result of a bad integration, however,\n * If the user id remains the same we don't throw error\n */\n if (this.userID === user.id && this.setUserPromise) {\n console.warn(\n 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',\n );\n return this.setUserPromise;\n }\n\n if (this.userID) {\n throw new Error(\n 'Use client.disconnect() before trying to connect as a different user. connectUser was called twice.',\n );\n }\n\n if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n // we generate the client id client side\n this.userID = user.id;\n this.anonymous = false;\n\n const setTokenPromise = this._setToken(user, userTokenOrProvider);\n this._setUser(user);\n\n const wsPromise = this.openConnection();\n\n this.setUserPromise = Promise.all([setTokenPromise, wsPromise]).then(\n (result) => result[1], // We only return connection promise;\n );\n\n try {\n return await this.setUserPromise;\n } catch (err) {\n if (this.persistUserOnConnectionFailure) {\n // cleanup client to allow the user to retry connectUser again\n this.closeConnection();\n } else {\n this.disconnectUser();\n }\n throw err;\n }\n };\n\n /**\n * @deprecated Please use connectUser() function instead. Its naming is more consistent with its functionality.\n *\n * setUser - Set the current user and open a WebSocket connection\n *\n * @param {OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n * @param {TokenOrProvider} userTokenOrProvider Token or provider\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n setUser = this.connectUser;\n\n _setToken = (user: UserResponse<StreamChatGenerics>, userTokenOrProvider: TokenOrProvider) =>\n this.tokenManager.setTokenOrProvider(userTokenOrProvider, user);\n\n _setUser(user: OwnUserResponse<StreamChatGenerics> | UserResponse<StreamChatGenerics>) {\n /**\n * This one is used by the frontend. This is a copy of the current user object stored on backend.\n * It contains reserved properties and own user properties which are not present in `this._user`.\n */\n this.user = user;\n this.userID = user.id;\n // this one is actually used for requests. This is a copy of current user provided to `connectUser` function.\n this._user = { ...user };\n }\n\n /**\n * Disconnects the websocket connection, without removing the user set on client.\n * client.closeConnection will not trigger default auto-retry mechanism for reconnection. You need\n * to call client.openConnection to reconnect to websocket.\n *\n * This is mainly useful on mobile side. You can only receive push notifications\n * if you don't have active websocket connection.\n * So when your app goes to background, you can call `client.closeConnection`.\n * And when app comes back to foreground, call `client.openConnection`.\n *\n * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming succesful disconnection.\n * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent\n */\n closeConnection = async (timeout?: number) => {\n if (this.cleaningIntervalRef != null) {\n clearInterval(this.cleaningIntervalRef);\n this.cleaningIntervalRef = undefined;\n }\n\n await Promise.all([this.wsConnection?.disconnect(timeout), this.wsFallback?.disconnect(timeout)]);\n return Promise.resolve();\n };\n\n /**\n * Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection\n */\n openConnection = async () => {\n if (!this.userID) {\n throw Error('User is not set on client, use client.connectUser or client.connectAnonymousUser instead');\n }\n\n if (this.wsConnection?.isConnecting && this.wsPromise) {\n this.logger('info', 'client:openConnection() - connection already in progress', {\n tags: ['connection', 'client'],\n });\n return this.wsPromise;\n }\n\n if ((this.wsConnection?.isHealthy || this.wsFallback?.isHealthy()) && this._hasConnectionID()) {\n this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists', {\n tags: ['connection', 'client'],\n });\n\n return;\n }\n\n this.clientID = `${this.userID}--${randomId()}`;\n this.wsPromise = this.connect();\n this._startCleaning();\n return this.wsPromise;\n };\n\n /**\n * @deprecated Please use client.openConnction instead.\n * @private\n *\n * Creates a new websocket connection with current user.\n */\n _setupConnection = this.openConnection;\n\n /**\n * updateAppSettings - updates application settings\n *\n * @param {AppSettings} options App settings.\n * IE: {\n 'apn_config': {\n 'auth_type': 'token',\n 'auth_key\": fs.readFileSync(\n './apn-push-auth-key.p8',\n 'utf-8',\n ),\n 'key_id': 'keyid',\n 'team_id': 'teamid',\n 'notification_template\": 'notification handlebars template',\n 'bundle_id': 'com.apple.your.app',\n 'development': true\n },\n 'firebase_config': {\n 'server_key': 'server key from fcm',\n 'notification_template': 'notification handlebars template',\n 'data_template': 'data handlebars template',\n 'apn_template': 'apn notification handlebars template under v2'\n },\n 'webhook_url': 'https://acme.com/my/awesome/webhook/'\n }\n */\n async updateAppSettings(options: AppSettings) {\n const apn_config = options.apn_config;\n if (apn_config?.p12_cert) {\n options = {\n ...options,\n apn_config: {\n ...apn_config,\n p12_cert: Buffer.from(apn_config.p12_cert).toString('base64'),\n },\n };\n }\n return await this.patch<APIResponse>(this.baseURL + '/app', options);\n }\n\n _normalizeDate = (before: Date | string | null): string | null => {\n if (before instanceof Date) {\n before = before.toISOString();\n }\n\n if (before === '') {\n throw new Error(\"Don't pass blank string for since, use null instead if resetting the token revoke\");\n }\n\n return before;\n };\n\n /**\n * Revokes all tokens on application level issued before given time\n */\n async revokeTokens(before: Date | string | null) {\n return await this.updateAppSettings({\n revoke_tokens_issued_before: this._normalizeDate(before),\n });\n }\n\n /**\n * Revokes token for a user issued before given time\n */\n async revokeUserToken(userID: string, before?: Date | string | null) {\n return await this.revokeUsersToken([userID], before);\n }\n\n /**\n * Revokes tokens for a list of users issued before given time\n */\n async revokeUsersToken(userIDs: string[], before?: Date | string | null) {\n if (before === undefined) {\n before = new Date().toISOString();\n } else {\n before = this._normalizeDate(before);\n }\n\n const users: PartialUserUpdate<StreamChatGenerics>[] = [];\n for (const userID of userIDs) {\n users.push({\n id: userID,\n set: <Partial<UserResponse<StreamChatGenerics>>>{\n revoke_tokens_issued_before: before,\n },\n });\n }\n\n return await this.partialUpdateUsers(users);\n }\n\n /**\n * getAppSettings - retrieves application settings\n */\n async getAppSettings() {\n return await this.get<AppSettingsAPIResponse<StreamChatGenerics>>(this.baseURL + '/app');\n }\n\n /**\n * testPushSettings - Tests the push settings for a user with a random chat message and the configured push templates\n *\n * @param {string} userID User ID. If user has no devices, it will error\n * @param {TestPushDataInput} [data] Overrides for push templates/message used\n * IE: {\n messageID: 'id-of-message', // will error if message does not exist\n apnTemplate: '{}', // if app doesn't have apn configured it will error\n firebaseTemplate: '{}', // if app doesn't have firebase configured it will error\n firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error\n skipDevices: true, // skip config/device checks and sending to real devices\n pushProviderName: 'staging' // one of your configured push providers\n pushProviderType: 'apn' // one of supported provider types\n }\n */\n async testPushSettings(userID: string, data: TestPushDataInput = {}) {\n return await this.post<CheckPushResponse>(this.baseURL + '/check_push', {\n user_id: userID,\n ...(data.messageID ? { message_id: data.messageID } : {}),\n ...(data.apnTemplate ? { apn_template: data.apnTemplate } : {}),\n ...(data.firebaseTemplate ? { firebase_template: data.firebaseTemplate } : {}),\n ...(data.firebaseDataTemplate ? { firebase_data_template: data.firebaseDataTemplate } : {}),\n ...(data.skipDevices ? { skip_devices: true } : {}),\n ...(data.pushProviderName ? { push_provider_name: data.pushProviderName } : {}),\n ...(data.pushProviderType ? { push_provider_type: data.pushProviderType } : {}),\n });\n }\n\n /**\n * testSQSSettings - Tests that the given or configured SQS configuration is valid\n *\n * @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed\n * IE: {\n sqs_key: 'auth_key',\n sqs_secret: 'auth_secret',\n sqs_url: 'url_to_queue',\n }\n */\n async testSQSSettings(data: TestSQSDataInput = {}) {\n return await this.post<CheckSQSResponse>(this.baseURL + '/check_sqs', data);\n }\n\n /**\n * testSNSSettings - Tests that the given or configured SNS configuration is valid\n *\n * @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed\n * IE: {\n sns_key: 'auth_key',\n sns_secret: 'auth_secret',\n sns_topic_arn: 'topic_to_publish_to',\n }\n */\n async testSNSSettings(data: TestSNSDataInput = {}) {\n return await this.post<CheckSNSResponse>(this.baseURL + '/check_sns', data);\n }\n\n /**\n * Disconnects the websocket and removes the user from client.\n *\n * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming successful disconnection.\n * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent\n */\n disconnectUser = async (timeout?: number) => {\n this.logger('info', 'client:disconnect() - Disconnecting the client', {\n tags: ['connection', 'client'],\n });\n\n // remove the user specific fields\n delete this.user;\n delete this._user;\n delete this.userID;\n\n this.anonymous = false;\n\n const closePromise = this.closeConnection(timeout);\n\n for (const channel of Object.values(this.activeChannels)) {\n channel._disconnect();\n }\n // ensure we no longer return inactive channels\n this.activeChannels = {};\n // reset client state\n this.state = new ClientState();\n // reset thread manager\n this.threads.resetState();\n // reset token manager\n setTimeout(this.tokenManager.reset); // delay reseting to use token for disconnect calls\n\n // close the WS connection\n return closePromise;\n };\n\n /**\n *\n * @deprecated Please use client.disconnectUser instead.\n *\n * Disconnects the websocket and removes the user from client.\n */\n disconnect = this.disconnectUser;\n\n /**\n * connectAnonymousUser - Set an anonymous user and open a WebSocket connection\n */\n connectAnonymousUser = () => {\n if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n this.anonymous = true;\n this.userID = randomId();\n const anonymousUser = {\n id: this.userID,\n anon: true,\n } as UserResponse<StreamChatGenerics>;\n\n this._setToken(anonymousUser, '');\n this._setUser(anonymousUser);\n\n return this._setupConnection();\n };\n\n /**\n * @deprecated Please use connectAnonymousUser. Its naming is more consistent with its functionality.\n */\n setAnonymousUser = this.connectAnonymousUser;\n\n /**\n * setGuestUser - Setup a temporary guest user\n *\n * @param {UserResponse<StreamChatGenerics>} user Data about this user. IE {name: \"john\"}\n *\n * @return {ConnectAPIResponse<StreamChatGenerics>} Returns a promise that resolves when the connection is setup\n */\n async setGuestUser(user: UserResponse<StreamChatGenerics>) {\n let response: { access_token: string; user: UserResponse<StreamChatGenerics> } | undefined;\n this.anonymous = true;\n try {\n response = await this.post<\n APIResponse & {\n access_token: string;\n user: UserResponse<StreamChatGenerics>;\n }\n >(this.baseURL + '/guest', { user });\n } catch (e) {\n this.anonymous = false;\n throw e;\n }\n this.anonymous = false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { created_at, updated_at, last_active, online, ...guestUser } = response.user;\n return await this.connectUser(guestUser as UserResponse<StreamChatGenerics>, response.access_token);\n }\n\n /**\n * createToken - Creates a token to authenticate this user. This function is used server side.\n * The resulting token should be passed to the client side when the users registers or logs in.\n *\n * @param {string} userID The User ID\n * @param {number} [exp] The expiration time for the token expressed in the number of seconds since the epoch\n *\n * @return {string} Returns a token\n */\n createToken(userID: string, exp?: number, iat?: number) {\n if (this.secret == null) {\n throw Error(`tokens can only be created server-side using the API Secret`);\n }\n const extra: { exp?: number; iat?: number } = {};\n\n if (exp) {\n extra.exp = exp;\n }\n\n if (iat) {\n extra.iat = iat;\n }\n\n return JWTUserToken(this.secret, userID, extra, {});\n }\n\n /**\n * on - Listen to events on all channels and users your watching\n *\n * client.on('message.new', event => {console.log(\"my new message\", event, channel.state.messages)})\n * or\n * client.on(event => {console.log(event.type)})\n *\n * @param {EventHandler<StreamChatGenerics> | string} callbackOrString The event type to listen for (optional)\n * @param {EventHandler<StreamChatGenerics>} [callbackOrNothing] The callback to call\n *\n * @return {{ unsubscribe: () => void }} Description\n */\n on(callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(eventType: string, callback: EventHandler<StreamChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<StreamChatGenerics> | string,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<StreamChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this.logger('info', `Attaching listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key].push(callback);\n return {\n unsubscribe: () => {\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n /**\n * off - Remove the event handler\n *\n */\n off(callback: EventHandler<StreamChatGenerics>): void;\n off(eventType: string, callback: EventHandler<StreamChatGenerics>): void;\n off(\n callbackOrString: EventHandler<StreamChatGenerics> | string,\n callbackOrNothing?: EventHandler<StreamChatGenerics>,\n ) {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<StreamChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger('info', `client: ${type} - Request - ${url}`, {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n });\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown) {\n this.logger('error', `client:${type} - Error - url: ${url}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n });\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n await this.tokenManager.tokenReady();\n const requestConfig = this._enrichAxiosOptions(options);\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e);\n this.consecutiveFailures += 1;\n if (e.response) {\n /** connection_fallback depends on this token expiration logic */\n if (e.response.data.code === chatCodes.TOKEN_EXPIRED && !this.tokenManager.isStatic()) {\n if (this.consecutiveFailures > 1) {\n await sleep(retryInterval(this.consecutiveFailures));\n }\n this.tokenManager.loadToken();\n return await this.doAxiosRequest<T>(type, url, data, options);\n }\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('post', url, data);\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n\n sendFile(\n url: string,\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<StreamChatGenerics>,\n ) {\n const data = addFileToFormData(uri, name, contentType || 'multipart/form-data');\n if (user != null) data.append('user', JSON.stringify(user));\n\n return this.doAxiosRequest<SendFileAPIResponse>('postForm', url, data, {\n headers: data.getHeaders ? data.getHeaders() : {}, // node vs browser\n config: {\n timeout: 0,\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n },\n });\n }\n\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`StreamChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`StreamChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n dispatchEvent = (event: Event<StreamChatGenerics>) => {\n if (!event.received_at) event.received_at = new Date();\n\n // client event handlers\n const postListenerCallbacks = this._handleClientEvent(event);\n\n // channel event handlers\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n };\n\n handleEvent = (messageEvent: WebSocket.MessageEvent) => {\n // dispatch the event to the channel listeners\n const jsonString = messageEvent.data as string;\n const event = JSON.parse(jsonString) as Event<StreamChatGenerics>;\n this.dispatchEvent(event);\n };\n\n /**\n * Updates the members, watchers and read references of the currently active channels that contain this user\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n _updateMemberWatcherReferences = (user: UserResponse<StreamChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n if (channel?.state) {\n if (channel.state.members[user.id]) {\n channel.state.members[user.id].user = user;\n }\n if (channel.state.watchers[user.id]) {\n channel.state.watchers[user.id] = user;\n }\n if (channel.state.read[user.id]) {\n channel.state.read[user.id].user = user;\n }\n }\n }\n };\n\n /**\n * @deprecated Please _updateMemberWatcherReferences instead.\n * @private\n */\n _updateUserReferences = this._updateMemberWatcherReferences;\n\n /**\n * @private\n *\n * Updates the messages from the currently active channels that contain this user,\n * with updated user object.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n */\n _updateUserMessageReferences = (user: UserResponse<StreamChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n\n if (!channel) continue;\n\n const state = channel.state;\n\n /** update the messages from this user. */\n state?.updateUserMessages(user);\n }\n };\n\n /**\n * @private\n *\n * Deletes the messages from the currently active channels that contain this user\n *\n * If hardDelete is true, all the content of message will be stripped down.\n * Otherwise, only 'message.type' will be set as 'deleted'.\n *\n * @param {UserResponse<StreamChatGenerics>} user\n * @param {boolean} hardDelete\n */\n _deleteUserMessageReference = (user: UserResponse<StreamChatGenerics>, hardDelete = false) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n const state = channel.state;\n\n /** deleted the messages from this user. */\n state?.deleteUserMessages(user, hardDelete);\n }\n };\n\n /**\n * @private\n *\n * Handle following user related events:\n * - user.presence.changed\n * - user.updated\n * - user.deleted\n *\n * @param {Event} event\n */\n _handleUserEvent = (event: Event<StreamChatGenerics>) => {\n if (!event.user) {\n return;\n }\n\n /** update the client.state with any changes to users */\n if (event.type === 'user.presence.changed' || event.type === 'user.updated') {\n if (event.user.id === this.userID) {\n const user = { ...(this.user || {}) };\n const _user = { ...(this._user || {}) };\n\n // Remove deleted properties from user objects.\n for (const key in this.user) {\n if (key in event.user || isOwnUserBaseProperty(key)) {\n continue;\n }\n\n delete user[key];\n delete _user[key];\n }\n\n /** Updating only available properties in _user object. */\n for (const key in event.user) {\n if (_user && key in _user) {\n _user[key] = event.user[key];\n }\n }\n\n // @ts-expect-error\n this._user = { ..._user };\n this.user = { ...user, ...event.user };\n }\n\n this.state.updateUser(event.user);\n this._updateMemberWatcherReferences(event.user);\n }\n\n if (event.type === 'user.updated') {\n this._updateUserMessageReferences(event.user);\n }\n\n if (event.type === 'user.deleted' && event.user.deleted_at && (event.mark_messages_deleted || event.hard_delete)) {\n this._deleteUserMessageReference(event.user, event.hard_delete);\n }\n };\n\n _handleClientEvent(event: Event<StreamChatGenerics>) {\n const client = this;\n const postListenerCallbacks = [];\n this.logger('info', `client:_handleClientEvent - Received event of type { ${event.type} }`, {\n tags: ['event', 'client'],\n event,\n });\n\n if (event.type === 'user.presence.changed' || event.type === 'user.updated' || event.type === 'user.deleted') {\n this._handleUserEvent(event);\n }\n\n if (event.type === 'health.check' && event.me) {\n client.user = event.me;\n client.state.updateUser(event.me);\n client.mutedChannels = event.me.channel_mutes;\n client.mutedUsers = event.me.mutes;\n }\n\n if (event.channel && event.type === 'notification.message_new') {\n this._addChannelConfig(event.channel);\n }\n\n if (event.type === 'notification.channel_mutes_updated' && event.me?.channel_mutes) {\n this.mutedChannels = event.me.channel_mutes;\n }\n\n if (event.type === 'notification.mutes_updated' && event.me?.mutes) {\n this.mutedUsers = event.me.mutes;\n }\n\n if (event.type === 'notification.mark_read' && event.unread_channels === 0) {\n const activeChannelKeys = Object.keys(this.activeChannels);\n activeChannelKeys.forEach((activeChannelKey) => (this.activeChannels[activeChannelKey].state.unreadCount = 0));\n }\n\n if ((event.type === 'channel.deleted' || event.type === 'notification.channel_deleted') && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n }\n\n return postListenerCallbacks;\n }\n\n _muteStatus(cid: string) {\n let muteStatus;\n for (let i = 0; i < this.mutedChannels.length; i++) {\n const mute = this.mutedChannels[i];\n if (mute.channel?.cid === cid) {\n muteStatus = {\n muted: mute.expires ? new Date(mute.expires).getTime() > new Date().getTime() : true,\n createdAt: mute.created_at ? new Date(mute.created_at) : new Date(),\n expiresAt: mute.expires ? new Date(mute.expires) : null,\n };\n break;\n }\n }\n\n if (muteStatus) {\n return muteStatus;\n }\n\n return {\n muted: false,\n createdAt: null,\n expiresAt: null,\n };\n }\n\n _callClientListeners = (event: Event<StreamChatGenerics>) => {\n const client = this;\n // gather and call the listeners\n const listeners: Array<(event: Event<StreamChatGenerics>) => void> = [];\n if (client.listeners.all) {\n listeners.push(...client.listeners.all);\n }\n if (client.listeners[event.type]) {\n listeners.push(...client.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n listener(event);\n }\n };\n\n recoverState = async () => {\n this.logger('info', `client:recoverState() - Start of recoverState with connectionID ${this._getConnectionID()}`, {\n tags: ['connection'],\n });\n\n const cids = Object.keys(this.activeChannels);\n if (cids.length && this.recoverStateOnReconnect) {\n this.logger('info', `client:recoverState() - Start the querying of ${cids.length} channels`, {\n tags: ['connection', 'client'],\n });\n\n await this.queryChannels(\n { cid: { $in: cids } } as ChannelFilters<StreamChatGenerics>,\n { last_message_at: -1 },\n { limit: 30 },\n );\n\n this.logger('info', 'client:recoverState() - Querying channels finished', { tags: ['connection', 'client'] });\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<StreamChatGenerics>);\n } else {\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<StreamChatGenerics>);\n }\n\n this.wsPromise = Promise.resolve();\n this.setUserPromise = Promise.resolve();\n };\n\n /**\n * @private\n */\n async connect() {\n if (!this.userID || !this._user) {\n throw Error('Call connectUser or connectAnonymousUser before starting the connection');\n }\n if (!this.wsBaseURL) {\n throw Error('Websocket base url not set');\n }\n if (!this.clientID) {\n throw Error('clientID is not set');\n }\n\n if (!this.wsConnection && (this.options.warmUp || this.options.enableInsights)) {\n this._sayHi();\n }\n // The StableWSConnection handles all the reconnection logic.\n if (this.options.wsConnection && this.node) {\n // Intentionally avoiding adding ts generics on wsConnection in options since its only useful for unit test purpose.\n ((this.options.wsConnection as unknown) as StableWSConnection<StreamChatGenerics>).setClient(this);\n this.wsConnection = (this.options.wsConnection as unknown) as StableWSConnection<StreamChatGenerics>;\n } else {\n this.wsConnection = new StableWSConnection<StreamChatGenerics>({\n client: this,\n });\n }\n\n try {\n // if fallback is used before, continue using it instead of waiting for WS to fail\n if (this.wsFallback) {\n return await this.wsFallback.connect();\n }\n\n // if WSFallback is enabled, ws connect should timeout faster so fallback can try\n return await this.wsConnection.connect(\n this.options.enableWSFallback ? this.defaultWSTimeoutWithFallback : this.defaultWSTimeout,\n );\n } catch (err) {\n // run fallback only if it's WS/Network error and not a normal API error\n // make sure browser is online before even trying the longpoll\n if (this.options.enableWSFallback && isWSFailure(err) && isOnline()) {\n this.logger('info', 'client:connect() - WS failed, fallback to longpoll', { tags: ['connection', 'client'] });\n this.dispatchEvent({ type: 'transport.changed', mode: 'longpoll' });\n\n this.wsConnection._destroyCurrentWSConnection();\n this.wsConnection.disconnect().then(); // close WS so no retry\n this.wsFallback = new WSConnectionFallback<StreamChatGenerics>({\n client: this,\n });\n return await this.wsFallback.connect();\n }\n\n throw err;\n }\n }\n\n /**\n * Check the connectivity with server for warmup purpose.\n *\n * @private\n */\n _sayHi() {\n const client_request_id = randomId();\n const opts = { headers: { 'x-client-request-id': client_request_id } };\n this.doAxiosRequest('get', this.baseURL + '/hi', null, opts).catch((e) => {\n if (this.options.enableInsights) {\n postInsights('http_hi_failed', {\n api_key: this.key,\n err: e,\n client_request_id,\n });\n }\n });\n }\n\n /**\n * queryUsers - Query users and watch user presence\n *\n * @param {UserFilters<StreamChatGenerics>} filterConditions MongoDB style filter conditions\n * @param {UserSort<StreamChatGenerics>} sort Sort options, for instance [{last_active: -1}].\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_active: -1}, {created_at: 1}]\n * @param {UserOptions} options Option object, {presence: true}\n *\n * @return {Promise<{ users: Array<UserResponse<StreamChatGenerics>> }>} User Query Response\n */\n async queryUsers(\n filterConditions: UserFilters<StreamChatGenerics>,\n sort: UserSort<StreamChatGenerics> = [],\n options: UserOptions = {},\n ) {\n const defaultOptions = {\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n if (!this._hasConnectionID()) {\n defaultOptions.presence = false;\n }\n\n // Return a list of users\n const data = await this.get<APIResponse & { users: Array<UserResponse<StreamChatGenerics>> }>(\n this.baseURL + '/users',\n {\n payload: {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...defaultOptions,\n ...options,\n },\n },\n );\n\n this.state.updateUsers(data.users);\n\n return data;\n }\n\n /**\n * queryBannedUsers - Query user bans\n *\n * @param {BannedUsersFilters} filterConditions MongoDB style filter conditions\n * @param {BannedUsersSort} sort Sort options [{created_at: 1}].\n * @param {BannedUsersPaginationOptions} options Option object, {limit: 10, offset:0, exclude_expired_bans: true}\n *\n * @return {Promise<BannedUsersResponse<StreamChatGenerics>>} Ban Query Response\n */\n async queryBannedUsers(\n filterConditions: BannedUsersFilters = {},\n sort: BannedUsersSort = [],\n options: BannedUsersPaginationOptions = {},\n ) {\n // Return a list of user bans\n return await this.get<BannedUsersResponse<StreamChatGenerics>>(this.baseURL + '/query_banned_users', {\n payload: {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n });\n }\n\n /**\n * queryMessageFlags - Query message flags\n *\n * @param {MessageFlagsFilters} filterConditions MongoDB style filter conditions\n * @param {MessageFlagsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<MessageFlagsResponse<StreamChatGenerics>>} Message Flags Response\n */\n async queryMessageFlags(filterConditions: MessageFlagsFilters = {}, options: MessageFlagsPaginationOptions = {}) {\n // Return a list of message flags\n return await this.get<MessageFlagsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flags/message', {\n payload: { filter_conditions: filterConditions, ...options },\n });\n }\n\n /**\n * queryChannels - Query channels\n *\n * @param {ChannelFilters<StreamChatGenerics>} filterConditions object MongoDB style filters\n * @param {ChannelSort<StreamChatGenerics>} [sort] Sort options, for instance {created_at: -1}.\n * When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{last_updated: -1}, {created_at: 1}]\n * @param {ChannelOptions} [options] Options object\n * @param {ChannelStateOptions} [stateOptions] State options object. These options will only be used for state management and won't be sent in the request.\n * - stateOptions.skipInitialization - Skips the initialization of the state for the channels matching the ids in the list.\n *\n * @return {Promise<{ channels: Array<ChannelAPIResponse<AStreamChatGenerics>>}> } search channels response\n */\n async queryChannels(\n filterConditions: ChannelFilters<StreamChatGenerics>,\n sort: ChannelSort<StreamChatGenerics> = [],\n options: ChannelOptions = {},\n stateOptions: ChannelStateOptions = {},\n ) {\n const defaultOptions: ChannelOptions = {\n state: true,\n watch: true,\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n if (!this._hasConnectionID()) {\n defaultOptions.watch = false;\n }\n\n // Return a list of channels\n const payload = {\n filter_conditions: filterConditions,\n sort: normalizeQuerySort(sort),\n ...defaultOptions,\n ...options,\n };\n\n const data = await this.post<QueryChannelsAPIResponse<StreamChatGenerics>>(this.baseURL + '/channels', payload);\n\n this.dispatchEvent({\n type: 'channels.queried',\n queriedChannels: {\n channels: data.channels,\n isLatestMessageSet: true,\n },\n });\n\n return this.hydrateActiveChannels(data.channels, stateOptions, options);\n }\n\n /**\n * queryReactions - Query reactions\n *\n * @param {ReactionFilters<StreamChatGenerics>} filter object MongoDB style filters\n * @param {ReactionSort<StreamChatGenerics>} [sort] Sort options, for instance {created_at: -1}.\n * @param {QueryReactionsOptions} [options] Pagination object\n *\n * @return {Promise<{ QueryReactionsAPIResponse } search channels response\n */\n async queryReactions(\n messageID: string,\n filter: ReactionFilters<StreamChatGenerics>,\n sort: ReactionSort<StreamChatGenerics> = [],\n options: QueryReactionsOptions = {},\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n // Return a list of channels\n const payload = {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n };\n\n return await this.post<QueryReactionsAPIResponse<StreamChatGenerics>>(\n this.baseURL + '/messages/' + encodeURIComponent(messageID) + '/reactions',\n payload,\n );\n }\n\n hydrateActiveChannels(\n channelsFromApi: ChannelAPIResponse<StreamChatGenerics>[] = [],\n stateOptions: ChannelStateOptions = {},\n queryChannelsOptions?: ChannelOptions,\n ) {\n const { skipInitialization, offlineMode = false } = stateOptions;\n const channels: Channel<StreamChatGenerics>[] = [];\n\n for (const channelState of channelsFromApi) {\n this._addChannelConfig(channelState.channel);\n const c = this.channel(channelState.channel.type, channelState.channel.id);\n c.data = channelState.channel;\n c.offlineMode = offlineMode;\n c.initialized = !offlineMode;\n\n let updatedMessagesSet;\n if (skipInitialization === undefined) {\n const { messageSet } = c._initializeState(channelState, 'latest');\n updatedMessagesSet = messageSet;\n } else if (!skipInitialization.includes(channelState.channel.id)) {\n c.state.clearMessages();\n const { messageSet } = c._initializeState(channelState, 'latest');\n updatedMessagesSet = messageSet;\n }\n\n if (updatedMessagesSet) {\n updatedMessagesSet.pagination = {\n ...updatedMessagesSet.pagination,\n ...messageSetPagination({\n parentSet: updatedMessagesSet,\n requestedPageSize: queryChannelsOptions?.message_limit || DEFAULT_QUERY_CHANNELS_MESSAGE_LIST_PAGE_SIZE,\n returnedPage: channelState.messages,\n logger: this.logger,\n }),\n };\n this.polls.hydratePollCache(updatedMessagesSet.messages, true);\n }\n\n channels.push(c);\n }\n\n return channels;\n }\n\n /**\n * search - Query messages\n *\n * @param {ChannelFilters<StreamChatGenerics>} filterConditions MongoDB style filter conditions\n * @param {MessageFilters<StreamChatGenerics> | string} query search query or object MongoDB style filters\n * @param {SearchOptions<StreamChatGenerics>} [options] Option object, {user_id: 'tommaso'}\n *\n * @return {Promise<SearchAPIResponse<StreamChatGenerics>>} search messages response\n */\n async search(\n filterConditions: ChannelFilters<StreamChatGenerics>,\n query: string | MessageFilters<StreamChatGenerics>,\n options: SearchOptions<StreamChatGenerics> = {},\n ) {\n if (options.offset && options.next) {\n throw Error(`Cannot specify offset with next`);\n }\n const payload: SearchPayload<StreamChatGenerics> = {\n filter_conditions: filterConditions,\n ...options,\n sort: options.sort ? normalizeQuerySort<SearchMessageSortBase<StreamChatGenerics>>(options.sort) : undefined,\n };\n if (typeof query === 'string') {\n payload.query = query;\n } else if (typeof query === 'object') {\n payload.message_filter_conditions = query;\n } else {\n throw Error(`Invalid type ${typeof query} for query parameter`);\n }\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n return await this.get<SearchAPIResponse<StreamChatGenerics>>(this.baseURL + '/search', { payload });\n }\n\n /**\n * setLocalDevice - Set the device info for the current client(device) that will be sent via WS connection automatically\n *\n * @param {BaseDeviceFields} device the device object\n * @param {string} device.id device id\n * @param {string} device.push_provider the push provider\n *\n */\n setLocalDevice(device: BaseDeviceFields) {\n if (\n (this.wsConnection?.isConnecting && this.wsPromise) ||\n ((this.wsConnection?.isHealthy || this.wsFallback?.isHealthy()) && this._hasConnectionID())\n ) {\n throw new Error('you can only set device before opening a websocket connection');\n }\n\n this.options.device = device;\n }\n\n /**\n * addDevice - Adds a push device for a user.\n *\n * @param {string} id the device id\n * @param {PushProvider} push_provider the push provider\n * @param {string} [userID] the user id (defaults to current user)\n * @param {string} [push_provider_name] user provided push provider name for multi bundle support\n *\n */\n async addDevice(id: string, push_provider: PushProvider, userID?: string, push_provider_name?: string) {\n return await this.post<APIResponse>(this.baseURL + '/devices', {\n id,\n push_provider,\n ...(userID != null ? { user_id: userID } : {}),\n ...(push_provider_name != null ? { push_provider_name } : {}),\n });\n }\n\n /**\n * getDevices - Returns the devices associated with a current user\n *\n * @param {string} [userID] User ID. Only works on serverside\n *\n * @return {Device<StreamChatGenerics>[]} Array of devices\n */\n async getDevices(userID?: string) {\n return await this.get<APIResponse & { devices?: Device<StreamChatGenerics>[] }>(\n this.baseURL + '/devices',\n userID ? { user_id: userID } : {},\n );\n }\n\n /**\n * getUnreadCount - Returns unread counts for a single user\n *\n * @param {string} [userID] User ID.\n *\n * @return {<GetUnreadCountAPIResponse>}\n */\n async getUnreadCount(userID?: string) {\n return await this.get<GetUnreadCountAPIResponse>(this.baseURL + '/unread', userID ? { user_id: userID } : {});\n }\n\n /**\n * getUnreadCountBatch - Returns unread counts for multiple users at once. Only works server side.\n *\n * @param {string[]} [userIDs] List of user IDs to fetch unread counts for.\n *\n * @return {<GetUnreadCountBatchAPIResponse>}\n */\n async getUnreadCountBatch(userIDs: string[]) {\n return await this.post<GetUnreadCountBatchAPIResponse>(this.baseURL + '/unread_batch', { user_ids: userIDs });\n }\n\n /**\n * removeDevice - Removes the device with the given id. Clientside users can only delete their own devices\n *\n * @param {string} id The device id\n * @param {string} [userID] The user id. Only specify this for serverside requests\n *\n */\n async removeDevice(id: string, userID?: string) {\n return await this.delete<APIResponse>(this.baseURL + '/devices', {\n id,\n ...(userID ? { user_id: userID } : {}),\n });\n }\n\n /**\n * getRateLimits - Returns the rate limits quota and usage for the current app, possibly filter for a specific platform and/or endpoints.\n * Only available server-side.\n *\n * @param {object} [params] The params for the call. If none of the params are set, all limits for all platforms are returned.\n * @returns {Promise<GetRateLimitsResponse>}\n */\n async getRateLimits(params?: {\n android?: boolean;\n endpoints?: EndpointName[];\n ios?: boolean;\n serverSide?: boolean;\n web?: boolean;\n }) {\n const { serverSide, web, android, ios, endpoints } = params || {};\n return this.get<GetRateLimitsResponse>(this.baseURL + '/rate_limits', {\n server_side: serverSide,\n web,\n android,\n ios,\n endpoints: endpoints ? endpoints.join(',') : undefined,\n });\n }\n\n _addChannelConfig({ cid, config }: ChannelResponse<StreamChatGenerics>) {\n this.configs[cid] = config;\n }\n\n /**\n * channel - Returns a new channel with the given type, id and custom data\n *\n * If you want to create a unique conversation between 2 or more users; you can leave out the ID parameter and provide the list of members.\n * Make sure to await channel.create() or channel.watch() before accessing channel functions:\n * ie. channel = client.channel(\"messaging\", {members: [\"tommaso\", \"thierry\"]})\n * await channel.create() to assign an ID to channel\n *\n * @param {string} channelType The channel type\n * @param {string | ChannelData<StreamChatGenerics> | null} [channelIDOrCustom] The channel ID, you can leave this out if you want to create a conversation channel\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n channel(\n channelType: string,\n channelID?: string | null,\n custom?: ChannelData<StreamChatGenerics>,\n ): Channel<StreamChatGenerics>;\n channel(channelType: string, custom?: ChannelData<StreamChatGenerics>): Channel<StreamChatGenerics>;\n channel(\n channelType: string,\n channelIDOrCustom?: string | ChannelData<StreamChatGenerics> | null,\n custom: ChannelData<StreamChatGenerics> = {} as ChannelData<StreamChatGenerics>,\n ) {\n if (!this.userID && !this._isUsingServerAuth()) {\n throw Error('Call connectUser or connectAnonymousUser before creating a channel');\n }\n\n if (~channelType.indexOf(':')) {\n throw Error(`Invalid channel group ${channelType}, can't contain the : character`);\n }\n\n // support channel(\"messaging\", {options})\n if (channelIDOrCustom && typeof channelIDOrCustom === 'object') {\n return this.getChannelByMembers(channelType, channelIDOrCustom);\n }\n\n // // support channel(\"messaging\", undefined, {options})\n if (!channelIDOrCustom && typeof custom === 'object' && custom.members?.length) {\n return this.getChannelByMembers(channelType, custom);\n }\n\n // support channel(\"messaging\", null, {options})\n // support channel(\"messaging\", undefined, {options})\n // support channel(\"messaging\", \"\", {options})\n if (!channelIDOrCustom) {\n return new Channel<StreamChatGenerics>(this, channelType, undefined, custom);\n }\n\n return this.getChannelById(channelType, channelIDOrCustom, custom);\n }\n\n /**\n * It's a helper method for `client.channel()` method, used to create unique conversation or\n * channel based on member list instead of id.\n *\n * If the channel already exists in `activeChannels` list, then we simply return it, since that\n * means the same channel was already requested or created.\n *\n * Otherwise we create a new instance of Channel class and return it.\n *\n * @private\n *\n * @param {string} channelType The channel type\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n getChannelByMembers = (channelType: string, custom: ChannelData<StreamChatGenerics>) => {\n // Check if the channel already exists.\n // Only allow 1 channel object per cid\n const membersStr = [...(custom.members || [])].sort().join(',');\n const tempCid = `${channelType}:!members-${membersStr}`;\n\n if (!membersStr) {\n throw Error('Please specify atleast one member when creating unique conversation');\n }\n\n // channel could exist in `activeChannels` list with either one of the following two keys:\n // 1. cid - Which gets set on channel only after calling channel.query or channel.watch or channel.create\n // 2. Sorted membersStr - E.g., \"messaging:amin,vishal\" OR \"messaging:amin,jaap,tom\"\n // This is set when you create a channel, but haven't queried yet. After query,\n // we will replace it with `cid`\n for (const key in this.activeChannels) {\n const channel = this.activeChannels[key];\n if (channel.disconnected) {\n continue;\n }\n\n if (key === tempCid) {\n return channel;\n }\n\n if (key.indexOf(`${channelType}:!members-`) === 0) {\n const membersStrInExistingChannel = Object.keys(channel.state.members).sort().join(',');\n if (membersStrInExistingChannel === membersStr) {\n return channel;\n }\n }\n }\n\n const channel = new Channel<StreamChatGenerics>(this, channelType, undefined, custom);\n\n // For the time being set the key as membersStr, since we don't know the cid yet.\n // In channel.query, we will replace it with 'cid'.\n this.activeChannels[tempCid] = channel;\n return channel;\n };\n\n /**\n * Its a helper method for `client.channel()` method, used to channel given the id of channel.\n *\n * If the channel already exists in `activeChannels` list, then we simply return it, since that\n * means the same channel was already requested or created.\n *\n * Otherwise we create a new instance of Channel class and return it.\n *\n * @private\n *\n * @param {string} channelType The channel type\n * @param {string} [channelID] The channel ID\n * @param {object} [custom] Custom data to attach to the channel\n *\n * @return {channel} The channel object, initialize it using channel.watch()\n */\n getChannelById = (channelType: string, channelID: string, custom: ChannelData<StreamChatGenerics>) => {\n if (typeof channelID === 'string' && ~channelID.indexOf(':')) {\n throw Error(`Invalid channel id ${channelID}, can't contain the : character`);\n }\n\n // only allow 1 channel object per cid\n const cid = `${channelType}:${channelID}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = { ...channel.data, ...custom };\n channel._data = { ...channel._data, ...custom };\n }\n return channel;\n }\n const channel = new Channel<StreamChatGenerics>(this, channelType, channelID, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n /**\n * partialUpdateUser - Update the given user object\n *\n * @param {PartialUserUpdate<StreamChatGenerics>} partialUserObject which should contain id and any of \"set\" or \"unset\" params;\n * example: {id: \"user1\", set:{field: value}, unset:[\"field2\"]}\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>} list of updated users\n */\n async partialUpdateUser(partialUserObject: PartialUserUpdate<StreamChatGenerics>) {\n return await this.partialUpdateUsers([partialUserObject]);\n }\n\n /**\n * upsertUsers - Batch upsert the list of users\n *\n * @param {UserResponse<StreamChatGenerics>[]} users list of users\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n async upsertUsers(users: UserResponse<StreamChatGenerics>[]) {\n const userMap: { [key: string]: UserResponse<StreamChatGenerics> } = {};\n for (const userObject of users) {\n if (!userObject.id) {\n throw Error('User ID is required when updating a user');\n }\n userMap[userObject.id] = userObject;\n }\n\n return await this.post<\n APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n }\n >(this.baseURL + '/users', { users: userMap });\n }\n\n /**\n * @deprecated Please use upsertUsers() function instead.\n *\n * updateUsers - Batch update the list of users\n *\n * @param {UserResponse<StreamChatGenerics>[]} users list of users\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n updateUsers = this.upsertUsers;\n\n /**\n * upsertUser - Update or Create the given user object\n *\n * @param {UserResponse<StreamChatGenerics>} userObject user object, the only required field is the user id. IE {id: \"myuser\"} is valid\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n upsertUser(userObject: UserResponse<StreamChatGenerics>) {\n return this.upsertUsers([userObject]);\n }\n\n /**\n * @deprecated Please use upsertUser() function instead.\n *\n * updateUser - Update or Create the given user object\n *\n * @param {UserResponse<StreamChatGenerics>} userObject user object, the only required field is the user id. IE {id: \"myuser\"} is valid\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n updateUser = this.upsertUser;\n\n /**\n * partialUpdateUsers - Batch partial update of users\n *\n * @param {PartialUserUpdate<StreamChatGenerics>[]} users list of partial update requests\n *\n * @return {Promise<{ users: { [key: string]: UserResponse<StreamChatGenerics> } }>}\n */\n async partialUpdateUsers(users: PartialUserUpdate<StreamChatGenerics>[]) {\n for (const userObject of users) {\n if (!userObject.id) {\n throw Error('User ID is required when updating a user');\n }\n }\n\n return await this.patch<\n APIResponse & {\n users: { [key: string]: UserResponse<StreamChatGenerics> };\n }\n >(this.baseURL + '/users', { users });\n }\n\n async deleteUser(\n userID: string,\n params?: {\n delete_conversation_channels?: boolean;\n hard_delete?: boolean;\n mark_messages_deleted?: boolean;\n },\n ) {\n return await this.delete<\n APIResponse & { user: UserResponse<StreamChatGenerics> } & {\n task_id?: string;\n }\n >(this.baseURL + `/users/${encodeURIComponent(userID)}`, params);\n }\n\n /**\n * restoreUsers - Restore soft deleted users\n *\n * @param {string[]} user_ids which users to restore\n *\n * @return {APIResponse} An API response\n */\n async restoreUsers(user_ids: string[]) {\n return await this.post<APIResponse>(this.baseURL + `/users/restore`, {\n user_ids,\n });\n }\n\n /**\n * reactivateUser - Reactivate one user\n *\n * @param {string} userID which user to reactivate\n * @param {ReactivateUserOptions} [options]\n *\n * @return {UserResponse} Reactivated user\n */\n async reactivateUser(userID: string, options?: ReactivateUserOptions) {\n return await this.post<APIResponse & { user: UserResponse<StreamChatGenerics> }>(\n this.baseURL + `/users/${encodeURIComponent(userID)}/reactivate`,\n { ...options },\n );\n }\n\n /**\n * reactivateUsers - Reactivate many users asynchronously\n *\n * @param {string[]} user_ids which users to reactivate\n * @param {ReactivateUsersOptions} [options]\n *\n * @return {TaskResponse} A task ID\n */\n async reactivateUsers(user_ids: string[], options?: ReactivateUsersOptions) {\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/reactivate`, { user_ids, ...options });\n }\n\n /**\n * deactivateUser - Deactivate one user\n *\n * @param {string} userID which user to deactivate\n * @param {DeactivateUsersOptions} [options]\n *\n * @return {UserResponse} Deactivated user\n */\n async deactivateUser(userID: string, options?: DeactivateUsersOptions) {\n return await this.post<APIResponse & { user: UserResponse<StreamChatGenerics> }>(\n this.baseURL + `/users/${encodeURIComponent(userID)}/deactivate`,\n { ...options },\n );\n }\n\n /**\n * deactivateUsers - Deactivate many users asynchronously\n *\n * @param {string[]} user_ids which users to deactivate\n * @param {DeactivateUsersOptions} [options]\n *\n * @return {TaskResponse} A task ID\n */\n async deactivateUsers(user_ids: string[], options?: DeactivateUsersOptions) {\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/deactivate`, { user_ids, ...options });\n }\n\n async exportUser(userID: string, options?: Record<string, string>) {\n return await this.get<\n APIResponse & {\n messages: MessageResponse<StreamChatGenerics>[];\n reactions: ReactionResponse<StreamChatGenerics>[];\n user: UserResponse<StreamChatGenerics>;\n }\n >(this.baseURL + `/users/${encodeURIComponent(userID)}/export`, { ...options });\n }\n\n /** banUser - bans a user from all channels\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<APIResponse>}\n */\n async banUser(targetUserID: string, options?: BanUserOptions<StreamChatGenerics>) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/ban', {\n target_user_id: targetUserID,\n ...options,\n });\n }\n\n /** unbanUser - revoke global ban for a user\n *\n * @param {string} targetUserID\n * @param {UnBanUserOptions} [options]\n * @returns {Promise<APIResponse>}\n */\n async unbanUser(targetUserID: string, options?: UnBanUserOptions) {\n return await this.delete<APIResponse>(this.baseURL + '/moderation/ban', {\n target_user_id: targetUserID,\n ...options,\n });\n }\n\n /** shadowBan - shadow bans a user from all channels\n *\n * @param {string} targetUserID\n * @param {BanUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<APIResponse>}\n */\n async shadowBan(targetUserID: string, options?: BanUserOptions<StreamChatGenerics>) {\n return await this.banUser(targetUserID, {\n shadow: true,\n ...options,\n });\n }\n\n /** removeShadowBan - revoke global shadow ban for a user\n *\n * @param {string} targetUserID\n * @param {UnBanUserOptions} [options]\n * @returns {Promise<APIResponse>}\n */\n async removeShadowBan(targetUserID: string, options?: UnBanUserOptions) {\n return await this.unbanUser(targetUserID, {\n shadow: true,\n ...options,\n });\n }\n async blockUser(blockedUserID: string, user_id?: string) {\n return await this.post<BlockUserAPIResponse>(this.baseURL + '/users/block', {\n blocked_user_id: blockedUserID,\n ...(user_id ? { user_id } : {}),\n });\n }\n\n async getBlockedUsers(user_id?: string) {\n return await this.get<GetBlockedUsersAPIResponse>(this.baseURL + '/users/block', {\n ...(user_id ? { user_id } : {}),\n });\n }\n async unBlockUser(blockedUserID: string, userID?: string) {\n return await this.post<APIResponse>(this.baseURL + '/users/unblock', {\n blocked_user_id: blockedUserID,\n ...(userID ? { user_id: userID } : {}),\n });\n }\n /** muteUser - mutes a user\n *\n * @param {string} targetID\n * @param {string} [userID] Only used with serverside auth\n * @param {MuteUserOptions<StreamChatGenerics>} [options]\n * @returns {Promise<MuteUserResponse<StreamChatGenerics>>}\n */\n async muteUser(targetID: string, userID?: string, options: MuteUserOptions<StreamChatGenerics> = {}) {\n return await this.post<MuteUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/mute', {\n target_id: targetID,\n ...(userID ? { user_id: userID } : {}),\n ...options,\n });\n }\n\n /** unmuteUser - unmutes a user\n *\n * @param {string} targetID\n * @param {string} [currentUserID] Only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unmuteUser(targetID: string, currentUserID?: string) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/unmute', {\n target_id: targetID,\n ...(currentUserID ? { user_id: currentUserID } : {}),\n });\n }\n\n /** userMuteStatus - check if a user is muted or not, can be used after connectUser() is called\n *\n * @param {string} targetID\n * @returns {boolean}\n */\n userMuteStatus(targetID: string) {\n if (!this.user || !this.wsPromise) {\n throw new Error('Make sure to await connectUser() first.');\n }\n\n for (let i = 0; i < this.mutedUsers.length; i += 1) {\n if (this.mutedUsers[i].target.id === targetID) return true;\n }\n return false;\n }\n\n /**\n * flagMessage - flag a message\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async flagMessage(targetMessageID: string, options: { reason?: string; user_id?: string } = {}) {\n return await this.post<FlagMessageResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flag', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n\n /**\n * flagUser - flag a user\n * @param {string} targetID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async flagUser(targetID: string, options: { reason?: string; user_id?: string } = {}) {\n return await this.post<FlagUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flag', {\n target_user_id: targetID,\n ...options,\n });\n }\n\n /**\n * unflagMessage - unflag a message\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unflagMessage(targetMessageID: string, options: { user_id?: string } = {}) {\n return await this.post<FlagMessageResponse<StreamChatGenerics>>(this.baseURL + '/moderation/unflag', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n\n /**\n * unflagUser - unflag a user\n * @param {string} targetID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unflagUser(targetID: string, options: { user_id?: string } = {}) {\n return await this.post<FlagUserResponse<StreamChatGenerics>>(this.baseURL + '/moderation/unflag', {\n target_user_id: targetID,\n ...options,\n });\n }\n\n /**\n * getCallToken - retrieves the auth token needed to join a call\n *\n * @param {string} callID\n * @param {object} options\n * @returns {Promise<GetCallTokenResponse>}\n */\n async getCallToken(callID: string, options: { user_id?: string } = {}) {\n return await this.post<GetCallTokenResponse>(this.baseURL + `/calls/${encodeURIComponent(callID)}`, { ...options });\n }\n\n /**\n * _queryFlags - Query flags.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {FlagsFilters} filterConditions MongoDB style filter conditions\n * @param {FlagsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<FlagsResponse<StreamChatGenerics>>} Flags Response\n */\n async _queryFlags(filterConditions: FlagsFilters = {}, options: FlagsPaginationOptions = {}) {\n // Return a list of flags\n return await this.post<FlagsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/flags', {\n filter_conditions: filterConditions,\n ...options,\n });\n }\n\n /**\n * _queryFlagReports - Query flag reports.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {FlagReportsFilters} filterConditions MongoDB style filter conditions\n * @param {FlagReportsPaginationOptions} options Option object, {limit: 10, offset:0}\n *\n * @return {Promise<FlagReportsResponse<StreamChatGenerics>>} Flag Reports Response\n */\n async _queryFlagReports(filterConditions: FlagReportsFilters = {}, options: FlagReportsPaginationOptions = {}) {\n // Return a list of message flags\n return await this.post<FlagReportsResponse<StreamChatGenerics>>(this.baseURL + '/moderation/reports', {\n filter_conditions: filterConditions,\n ...options,\n });\n }\n\n /**\n * _reviewFlagReport - review flag report\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} [id] flag report to review\n * @param {string} [reviewResult] flag report review result\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @param {string} [options.review_details] custom information about review result\n * @returns {Promise<ReviewFlagReportResponse>>}\n */\n async _reviewFlagReport(id: string, reviewResult: string, options: ReviewFlagReportOptions = {}) {\n return await this.patch<ReviewFlagReportResponse<StreamChatGenerics>>(\n this.baseURL + `/moderation/reports/${encodeURIComponent(id)}`,\n {\n review_result: reviewResult,\n ...options,\n },\n );\n }\n\n /**\n * unblockMessage - unblocks message blocked by automod\n *\n *\n * @param {string} targetMessageID\n * @param {string} [options.user_id] currentUserID, only used with serverside auth\n * @returns {Promise<APIResponse>}\n */\n async unblockMessage(targetMessageID: string, options: { user_id?: string } = {}) {\n return await this.post<APIResponse>(this.baseURL + '/moderation/unblock_message', {\n target_message_id: targetMessageID,\n ...options,\n });\n }\n // alias for backwards compatibility\n _unblockMessage = this.unblockMessage;\n\n /**\n * @deprecated use markChannelsRead instead\n *\n * markAllRead - marks all channels for this user as read\n * @param {MarkAllReadOptions<StreamChatGenerics>} [data]\n *\n * @return {Promise<APIResponse>}\n */\n markAllRead = this.markChannelsRead;\n\n /**\n * markChannelsRead - marks channels read -\n * it accepts a map of cid:messageid pairs, if messageid is empty, the whole channel will be marked as read\n *\n * @param {MarkChannelsReadOptions <StreamChatGenerics>} [data]\n *\n * @return {Promise<APIResponse>}\n */\n async markChannelsRead(data: MarkChannelsReadOptions<StreamChatGenerics> = {}) {\n await this.post<APIResponse>(this.baseURL + '/channels/read', { ...data });\n }\n\n createCommand(data: CreateCommandOptions<StreamChatGenerics>) {\n return this.post<CreateCommandResponse<StreamChatGenerics>>(this.baseURL + '/commands', data);\n }\n\n getCommand(name: string) {\n return this.get<GetCommandResponse<StreamChatGenerics>>(this.baseURL + `/commands/${encodeURIComponent(name)}`);\n }\n\n updateCommand(name: string, data: UpdateCommandOptions<StreamChatGenerics>) {\n return this.put<UpdateCommandResponse<StreamChatGenerics>>(\n this.baseURL + `/commands/${encodeURIComponent(name)}`,\n data,\n );\n }\n\n deleteCommand(name: string) {\n return this.delete<DeleteCommandResponse<StreamChatGenerics>>(\n this.baseURL + `/commands/${encodeURIComponent(name)}`,\n );\n }\n\n listCommands() {\n return this.get<ListCommandsResponse<StreamChatGenerics>>(this.baseURL + `/commands`);\n }\n\n createChannelType(data: CreateChannelOptions<StreamChatGenerics>) {\n const channelData = Object.assign({}, { commands: ['all'] }, data);\n return this.post<CreateChannelResponse<StreamChatGenerics>>(this.baseURL + '/channeltypes', channelData);\n }\n\n getChannelType(channelType: string) {\n return this.get<GetChannelTypeResponse<StreamChatGenerics>>(\n this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`,\n );\n }\n\n updateChannelType(channelType: string, data: UpdateChannelOptions<StreamChatGenerics>) {\n return this.put<UpdateChannelResponse<StreamChatGenerics>>(\n this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`,\n data,\n );\n }\n\n deleteChannelType(channelType: string) {\n return this.delete<APIResponse>(this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`);\n }\n\n listChannelTypes() {\n return this.get<ListChannelResponse<StreamChatGenerics>>(this.baseURL + `/channeltypes`);\n }\n\n /**\n * translateMessage - adds the translation to the message\n *\n * @param {string} messageId\n * @param {string} language\n *\n * @return {MessageResponse<StreamChatGenerics>} Response that includes the message\n */\n async translateMessage(messageId: string, language: string) {\n return await this.post<APIResponse & MessageResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageId)}/translate`,\n { language },\n );\n }\n\n /**\n * _normalizeExpiration - transforms expiration value into ISO string\n * @param {undefined|null|number|string|Date} timeoutOrExpirationDate expiration date or timeout. Use number type to set timeout in seconds, string or Date to set exact expiration date\n */\n _normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {\n let pinExpires: null | string = null;\n if (typeof timeoutOrExpirationDate === 'number') {\n const now = new Date();\n now.setSeconds(now.getSeconds() + timeoutOrExpirationDate);\n pinExpires = now.toISOString();\n } else if (isString(timeoutOrExpirationDate)) {\n pinExpires = timeoutOrExpirationDate;\n } else if (timeoutOrExpirationDate instanceof Date) {\n pinExpires = timeoutOrExpirationDate.toISOString();\n }\n return pinExpires;\n }\n\n /**\n * _messageId - extracts string message id from either message object or message id\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {string} errorText error message to report in case of message id absence\n */\n _validateAndGetMessageId(messageOrMessageId: string | { id: string }, errorText: string) {\n let messageId: string;\n if (typeof messageOrMessageId === 'string') {\n messageId = messageOrMessageId;\n } else {\n if (!messageOrMessageId.id) {\n throw Error(errorText);\n }\n messageId = messageOrMessageId.id;\n }\n return messageId;\n }\n\n /**\n * pinMessage - pins the message\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {undefined|null|number|string|Date} timeoutOrExpirationDate expiration date or timeout. Use number type to set timeout in seconds, string or Date to set exact expiration date\n * @param {undefined|string | { id: string }} [pinnedBy] who will appear as a user who pinned a message. Only for server-side use. Provide `undefined` when pinning message client-side\n * @param {undefined|number|string|Date} pinnedAt date when message should be pinned. It affects the order of pinned messages. Use negative number to set relative time in the past, string or Date to set exact date of pin\n */\n pinMessage(\n messageOrMessageId: string | { id: string },\n timeoutOrExpirationDate?: null | number | string | Date,\n pinnedBy?: string | { id: string },\n pinnedAt?: number | string | Date,\n ) {\n const messageId = this._validateAndGetMessageId(\n messageOrMessageId,\n 'Please specify the message id when calling unpinMessage',\n );\n return this.partialUpdateMessage(\n messageId,\n ({\n set: {\n pinned: true,\n pin_expires: this._normalizeExpiration(timeoutOrExpirationDate),\n pinned_at: this._normalizeExpiration(pinnedAt),\n },\n } as unknown) as PartialMessageUpdate<StreamChatGenerics>,\n pinnedBy,\n );\n }\n\n /**\n * unpinMessage - unpins the message that was previously pinned\n * @param {string | { id: string }} messageOrMessageId message object or message id\n * @param {string | { id: string }} [userId]\n */\n unpinMessage(messageOrMessageId: string | { id: string }, userId?: string | { id: string }) {\n const messageId = this._validateAndGetMessageId(\n messageOrMessageId,\n 'Please specify the message id when calling unpinMessage',\n );\n return this.partialUpdateMessage(\n messageId,\n ({\n set: { pinned: false },\n } as unknown) as PartialMessageUpdate<StreamChatGenerics>,\n userId,\n );\n }\n\n /**\n * updateMessage - Update the given message\n *\n * @param {Omit<MessageResponse<StreamChatGenerics>, 'mentioned_users'> & { mentioned_users?: string[] }} message object, id needs to be specified\n * @param {string | { id: string }} [userId]\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the message\n */\n async updateMessage(\n message: UpdatedMessage<StreamChatGenerics>,\n userId?: string | { id: string },\n options?: UpdateMessageOptions,\n ) {\n if (!message.id) {\n throw Error('Please specify the message id when calling updateMessage');\n }\n\n const clonedMessage: Message = Object.assign({}, message);\n delete clonedMessage.id;\n\n const reservedMessageFields: Array<ReservedMessageFields> = [\n 'command',\n 'created_at',\n 'html',\n 'latest_reactions',\n 'own_reactions',\n 'quoted_message',\n 'reaction_counts',\n 'reply_count',\n 'type',\n 'updated_at',\n 'user',\n '__html',\n ];\n\n reservedMessageFields.forEach(function (item) {\n if (clonedMessage[item] != null) {\n delete clonedMessage[item];\n }\n });\n\n if (userId != null) {\n if (isString(userId)) {\n clonedMessage.user_id = userId;\n } else {\n clonedMessage.user = {\n id: userId.id,\n } as UserResponse<StreamChatGenerics>;\n }\n }\n\n /**\n * Server always expects mentioned_users to be array of string. We are adding extra check, just in case\n * SDK missed this conversion.\n */\n if (Array.isArray(clonedMessage.mentioned_users) && !isString(clonedMessage.mentioned_users[0])) {\n clonedMessage.mentioned_users = clonedMessage.mentioned_users.map((mu) => ((mu as unknown) as UserResponse).id);\n }\n\n return await this.post<UpdateMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(message.id as string)}`,\n {\n message: clonedMessage,\n ...options,\n },\n );\n }\n\n /**\n * partialUpdateMessage - Update the given message id while retaining additional properties\n *\n * @param {string} id the message id\n *\n * @param {PartialUpdateMessage<StreamChatGenerics>} partialMessageObject which should contain id and any of \"set\" or \"unset\" params;\n * example: {id: \"user1\", set:{text: \"hi\"}, unset:[\"color\"]}\n * @param {string | { id: string }} [userId]\n *\n * @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the updated message\n */\n async partialUpdateMessage(\n id: string,\n partialMessageObject: PartialMessageUpdate<StreamChatGenerics>,\n userId?: string | { id: string },\n options?: UpdateMessageOptions,\n ) {\n if (!id) {\n throw Error('Please specify the message id when calling partialUpdateMessage');\n }\n let user = userId;\n if (userId != null && isString(userId)) {\n user = { id: userId };\n }\n return await this.put<UpdateMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(id)}`,\n {\n ...partialMessageObject,\n ...options,\n user,\n },\n );\n }\n\n async deleteMessage(messageID: string, hardDelete?: boolean) {\n let params = {};\n if (hardDelete) {\n params = { hard: true };\n }\n return await this.delete<APIResponse & { message: MessageResponse<StreamChatGenerics> }>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}`,\n params,\n );\n }\n\n /**\n * undeleteMessage - Undelete a message\n *\n * undeletes a message that was previous soft deleted. Hard deleted messages\n * cannot be undeleted. This is only allowed to be called from server-side\n * clients.\n *\n * @param {string} messageID The id of the message to undelete\n * @param {string} userID The id of the user who undeleted the message\n *\n * @return {{ message: MessageResponse<StreamChatGenerics> }} Response that includes the message\n */\n async undeleteMessage(messageID: string, userID: string) {\n return await this.post<APIResponse & { message: MessageResponse<StreamChatGenerics> }>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}/undelete`,\n { undeleted_by: userID },\n );\n }\n\n async getMessage(messageID: string, options?: GetMessageOptions) {\n return await this.get<GetMessageAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageID)}`,\n { ...options },\n );\n }\n\n /**\n * queryThreads - returns the list of threads of current user.\n *\n * @param {QueryThreadsOptions} options Options object for pagination and limiting the participants and replies.\n * @param {number} options.limit Limits the number of threads to be returned.\n * @param {boolean} options.watch Subscribes the user to the channels of the threads.\n * @param {number} options.participant_limit Limits the number of participants returned per threads.\n * @param {number} options.reply_limit Limits the number of replies returned per threads.\n *\n * @returns {{ threads: Thread<StreamChatGenerics>[], next: string }} Returns the list of threads and the next cursor.\n */\n async queryThreads(options?: QueryThreadsOptions) {\n const opts = {\n limit: 10,\n participant_limit: 10,\n reply_limit: 3,\n watch: true,\n ...options,\n };\n\n const res = await this.post<QueryThreadsAPIResponse<StreamChatGenerics>>(this.baseURL + `/threads`, opts);\n\n return {\n threads: res.threads.map((thread) => new Thread({ client: this, threadData: thread })),\n next: res.next,\n };\n }\n\n /**\n * getThread - returns the thread of a message by its id.\n *\n * @param {string} messageId The message id\n * @param {GetThreadOptions} options Options object for pagination and limiting the participants and replies.\n * @param {boolean} options.watch Subscribes the user to the channel of the thread.\n * @param {number} options.participant_limit Limits the number of participants returned per threads.\n * @param {number} options.reply_limit Limits the number of replies returned per threads.\n *\n * @returns {Thread<StreamChatGenerics>} Returns the thread.\n */\n async getThread(messageId: string, options: GetThreadOptions = {}) {\n if (!messageId) {\n throw Error('Please specify the message id when calling partialUpdateThread');\n }\n\n const opts = {\n participant_limit: 100,\n reply_limit: 3,\n watch: true,\n ...options,\n };\n\n const res = await this.get<GetThreadAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/threads/${encodeURIComponent(messageId)}`,\n opts,\n );\n\n return new Thread<StreamChatGenerics>({ client: this, threadData: res.thread });\n }\n\n /**\n * partialUpdateThread - updates the given thread\n *\n * @param {string} messageId The id of the thread message which needs to be updated.\n * @param {PartialThreadUpdate} partialThreadObject should contain \"set\" or \"unset\" params for any of the thread's non-reserved fields.\n *\n * @returns {GetThreadAPIResponse<StreamChatGenerics>} Returns the updated thread.\n */\n async partialUpdateThread(messageId: string, partialThreadObject: PartialThreadUpdate) {\n if (!messageId) {\n throw Error('Please specify the message id when calling partialUpdateThread');\n }\n\n // check for reserved fields from ThreadResponse type within partialThreadObject's set and unset.\n // Throw error if any of the reserved field is found.\n const reservedThreadFields = [\n 'created_at',\n 'id',\n 'last_message_at',\n 'type',\n 'updated_at',\n 'user',\n 'reply_count',\n 'participants',\n 'channel',\n ];\n\n for (const key in { ...partialThreadObject.set, ...partialThreadObject.unset }) {\n if (reservedThreadFields.includes(key)) {\n throw Error(\n `You cannot set ${key} field on Thread object. ${key} is reserved for server-side use. Please omit ${key} from your set object.`,\n );\n }\n }\n\n return await this.patch<GetThreadAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/threads/${encodeURIComponent(messageId)}`,\n partialThreadObject,\n );\n }\n\n getUserAgent() {\n return (\n this.userAgent || `stream-chat-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n\n /**\n * _isUsingServerAuth - Returns true if we're using server side auth\n */\n _isUsingServerAuth = () => !!this.secret;\n\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n const token = this._getToken();\n const authorization = token ? { Authorization: token } : undefined;\n let signal: AbortSignal | null = null;\n if (this.nextRequestAbortController !== null) {\n signal = this.nextRequestAbortController.signal;\n this.nextRequestAbortController = null;\n }\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n\n const { params: axiosRequestConfigParams, headers: axiosRequestConfigHeaders, ...axiosRequestConfigRest } =\n this.options.axiosRequestConfig || {};\n\n return {\n params: {\n user_id: this.userID,\n connection_id: this._getConnectionID(),\n api_key: this.key,\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n },\n headers: {\n ...authorization,\n 'stream-auth-type': this.getAuthType(),\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n ...(signal ? { signal } : {}),\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n _getToken() {\n if (!this.tokenManager || this.anonymous) return null;\n\n return this.tokenManager.getToken();\n }\n\n _startCleaning() {\n const that = this;\n if (this.cleaningIntervalRef != null) {\n return;\n }\n this.cleaningIntervalRef = setInterval(() => {\n // call clean on the channel, used for calling the stop.typing event etc.\n for (const channel of Object.values(that.activeChannels)) {\n channel.clean();\n }\n }, 500);\n }\n\n /**\n * encode ws url payload\n * @private\n * @returns json string\n */\n _buildWSPayload = (client_request_id?: string) => {\n return JSON.stringify({\n user_id: this.userID,\n user_details: this._user,\n device: this.options.device,\n client_request_id,\n });\n };\n\n /**\n * checks signature of a request\n * @param {string | Buffer} rawBody\n * @param {string} signature from HTTP header\n * @returns {boolean}\n */\n verifyWebhook(requestBody: string | Buffer, xSignature: string) {\n return !!this.secret && CheckSignature(requestBody, this.secret, xSignature);\n }\n\n /** getPermission - gets the definition for a permission\n *\n * @param {string} name\n * @returns {Promise<PermissionAPIResponse>}\n */\n getPermission(name: string) {\n return this.get<PermissionAPIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(name)}`);\n }\n\n /** createPermission - creates a custom permission\n *\n * @param {CustomPermissionOptions} permissionData the permission data\n * @returns {Promise<APIResponse>}\n */\n createPermission(permissionData: CustomPermissionOptions) {\n return this.post<APIResponse>(`${this.baseURL}/permissions`, {\n ...permissionData,\n });\n }\n\n /** updatePermission - updates an existing custom permission\n *\n * @param {string} id\n * @param {Omit<CustomPermissionOptions, 'id'>} permissionData the permission data\n * @returns {Promise<APIResponse>}\n */\n updatePermission(id: string, permissionData: Omit<CustomPermissionOptions, 'id'>) {\n return this.put<APIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(id)}`, {\n ...permissionData,\n });\n }\n\n /** deletePermission - deletes a custom permission\n *\n * @param {string} name\n * @returns {Promise<APIResponse>}\n */\n deletePermission(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/permissions/${encodeURIComponent(name)}`);\n }\n\n /** listPermissions - returns the list of all permissions for this application\n *\n * @returns {Promise<APIResponse>}\n */\n listPermissions() {\n return this.get<PermissionsAPIResponse>(`${this.baseURL}/permissions`);\n }\n\n /** createRole - creates a custom role\n *\n * @param {string} name the new role name\n * @returns {Promise<APIResponse>}\n */\n createRole(name: string) {\n return this.post<APIResponse>(`${this.baseURL}/roles`, { name });\n }\n\n /** listRoles - returns the list of all roles for this application\n *\n * @returns {Promise<APIResponse>}\n */\n listRoles() {\n return this.get<APIResponse>(`${this.baseURL}/roles`);\n }\n\n /** deleteRole - deletes a custom role\n *\n * @param {string} name the role name\n * @returns {Promise<APIResponse>}\n */\n deleteRole(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/roles/${encodeURIComponent(name)}`);\n }\n\n /** sync - returns all events that happened for a list of channels since last sync\n * @param {string[]} channel_cids list of channel CIDs\n * @param {string} last_sync_at last time the user was online and in sync. RFC3339 ie. \"2020-05-06T15:05:01.207Z\"\n * @param {SyncOptions} options See JSDoc in the type fields for more info\n *\n * @returns {Promise<SyncResponse>}\n */\n sync(channel_cids: string[], last_sync_at: string, options: SyncOptions = {}) {\n return this.post<SyncResponse>(`${this.baseURL}/sync`, {\n channel_cids,\n last_sync_at,\n ...options,\n });\n }\n\n /**\n * sendUserCustomEvent - Send a custom event to a user\n *\n * @param {string} targetUserID target user id\n * @param {UserCustomEvent} event for example {type: 'friendship-request'}\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async sendUserCustomEvent(targetUserID: string, event: UserCustomEvent) {\n return await this.post<APIResponse>(`${this.baseURL}/users/${encodeURIComponent(targetUserID)}/event`, {\n event,\n });\n }\n\n createBlockList(blockList: BlockList) {\n return this.post<APIResponse>(`${this.baseURL}/blocklists`, blockList);\n }\n\n listBlockLists() {\n return this.get<APIResponse & { blocklists: BlockListResponse[] }>(`${this.baseURL}/blocklists`);\n }\n\n getBlockList(name: string) {\n return this.get<APIResponse & { blocklist: BlockListResponse }>(\n `${this.baseURL}/blocklists/${encodeURIComponent(name)}`,\n );\n }\n\n updateBlockList(name: string, data: { words: string[] }) {\n return this.put<APIResponse>(`${this.baseURL}/blocklists/${encodeURIComponent(name)}`, data);\n }\n\n deleteBlockList(name: string) {\n return this.delete<APIResponse>(`${this.baseURL}/blocklists/${encodeURIComponent(name)}`);\n }\n\n exportChannels(request: Array<ExportChannelRequest>, options: ExportChannelOptions = {}) {\n const payload = { channels: request, ...options };\n return this.post<APIResponse & ExportChannelResponse>(`${this.baseURL}/export_channels`, payload);\n }\n\n exportUsers(request: ExportUsersRequest) {\n return this.post<APIResponse & ExportUsersResponse>(`${this.baseURL}/export/users`, request);\n }\n\n exportChannel(request: ExportChannelRequest, options?: ExportChannelOptions) {\n return this.exportChannels([request], options);\n }\n\n getExportChannelStatus(id: string) {\n return this.get<APIResponse & ExportChannelStatusResponse>(\n `${this.baseURL}/export_channels/${encodeURIComponent(id)}`,\n );\n }\n\n campaign(idOrData: string | CampaignData, data?: CampaignData) {\n if (idOrData && typeof idOrData === 'object') {\n return new Campaign(this, null, idOrData);\n }\n\n return new Campaign(this, idOrData, data);\n }\n\n segment(type: SegmentType, idOrData: string | SegmentData, data?: SegmentData) {\n if (typeof idOrData === 'string') {\n return new Segment(this, type, idOrData, data);\n }\n\n return new Segment(this, type, null, idOrData);\n }\n\n validateServerSideAuth() {\n if (!this.secret) {\n throw new Error(\n 'Campaigns is a server-side only feature. Please initialize the client with a secret to use this feature.',\n );\n }\n }\n\n /**\n * createSegment - Creates a segment\n *\n * @private\n * @param {SegmentType} type Segment type\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} params Segment data\n *\n * @return {{segment: SegmentResponse} & APIResponse} The created Segment\n */\n async createSegment(type: SegmentType, id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n const body = {\n id,\n type,\n ...data,\n };\n return this.post<{ segment: SegmentResponse }>(this.baseURL + `/segments`, body);\n }\n\n /**\n * createUserSegment - Creates a user segment\n *\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} data Segment data\n *\n * @return {Segment} The created Segment\n */\n async createUserSegment(id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n return this.createSegment('user', id, data);\n }\n\n /**\n * createChannelSegment - Creates a channel segment\n *\n * @param {string} id Segment ID\n * @param {string} name Segment name\n * @param {SegmentData} data Segment data\n *\n * @return {Segment} The created Segment\n */\n async createChannelSegment(id: string | null, data?: SegmentData) {\n this.validateServerSideAuth();\n return this.createSegment('channel', id, data);\n }\n\n async getSegment(id: string) {\n this.validateServerSideAuth();\n return this.get<{ segment: SegmentResponse } & APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}`);\n }\n\n /**\n * updateSegment - Update a segment\n *\n * @param {string} id Segment ID\n * @param {Partial<UpdateSegmentData>} data Data to update\n *\n * @return {Segment} Updated Segment\n */\n async updateSegment(id: string, data: Partial<UpdateSegmentData>) {\n this.validateServerSideAuth();\n return this.put<{ segment: SegmentResponse }>(this.baseURL + `/segments/${encodeURIComponent(id)}`, data);\n }\n\n /**\n * addSegmentTargets - Add targets to a segment\n *\n * @param {string} id Segment ID\n * @param {string[]} targets Targets to add to the segment\n *\n * @return {APIResponse} API response\n */\n async addSegmentTargets(id: string, targets: string[]) {\n this.validateServerSideAuth();\n const body = { target_ids: targets };\n return this.post<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}/addtargets`, body);\n }\n\n async querySegmentTargets(\n id: string,\n filter: QuerySegmentTargetsFilter | null = {},\n sort: SortParam[] | null | [] = [],\n options = {},\n ) {\n this.validateServerSideAuth();\n return this.post<{ targets: SegmentTargetsResponse[]; next?: string } & APIResponse>(\n this.baseURL + `/segments/${encodeURIComponent(id)}/targets/query`,\n {\n filter: filter || {},\n sort: sort || [],\n ...options,\n },\n );\n }\n /**\n * removeSegmentTargets - Remove targets from a segment\n *\n * @param {string} id Segment ID\n * @param {string[]} targets Targets to add to the segment\n *\n * @return {APIResponse} API response\n */\n async removeSegmentTargets(id: string, targets: string[]) {\n this.validateServerSideAuth();\n const body = { target_ids: targets };\n return this.post<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}/deletetargets`, body);\n }\n\n /**\n * querySegments - Query Segments\n *\n * @param {filter} filter MongoDB style filter conditions\n * @param {QuerySegmentsOptions} options Options for sorting/paginating the results\n *\n * @return {Segment[]} Segments\n */\n async querySegments(filter: {}, sort?: SortParam[], options: QuerySegmentsOptions = {}) {\n this.validateServerSideAuth();\n return this.post<\n {\n segments: SegmentResponse[];\n next?: string;\n prev?: string;\n } & APIResponse\n >(this.baseURL + `/segments/query`, {\n filter,\n sort,\n ...options,\n });\n }\n\n /**\n * deleteSegment - Delete a Campaign Segment\n *\n * @param {string} id Segment ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async deleteSegment(id: string) {\n this.validateServerSideAuth();\n return this.delete<APIResponse>(this.baseURL + `/segments/${encodeURIComponent(id)}`);\n }\n\n /**\n * segmentTargetExists - Check if a target exists in a segment\n *\n * @param {string} segmentId Segment ID\n * @param {string} targetId Target ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async segmentTargetExists(segmentId: string, targetId: string) {\n this.validateServerSideAuth();\n return this.get<APIResponse>(\n this.baseURL + `/segments/${encodeURIComponent(segmentId)}/target/${encodeURIComponent(targetId)}`,\n );\n }\n\n /**\n * createCampaign - Creates a Campaign\n *\n * @param {CampaignData} params Campaign data\n *\n * @return {Campaign} The Created Campaign\n */\n async createCampaign(params: CampaignData) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse } & APIResponse>(this.baseURL + `/campaigns`, { ...params });\n }\n\n async getCampaign(id: string) {\n this.validateServerSideAuth();\n return this.get<{ campaign: CampaignResponse } & APIResponse>(\n this.baseURL + `/campaigns/${encodeURIComponent(id)}`,\n );\n }\n\n async startCampaign(id: string, options?: { scheduledFor?: string; stopAt?: string }) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse } & APIResponse>(\n this.baseURL + `/campaigns/${encodeURIComponent(id)}/start`,\n {\n scheduled_for: options?.scheduledFor,\n stop_at: options?.stopAt,\n },\n );\n }\n /**\n * queryCampaigns - Query Campaigns\n *\n *\n * @return {Campaign[]} Campaigns\n */\n async queryCampaigns(filter: CampaignFilters, sort?: CampaignSort, options?: CampaignQueryOptions) {\n this.validateServerSideAuth();\n return await this.post<\n {\n campaigns: CampaignResponse[];\n next?: string;\n prev?: string;\n } & APIResponse\n >(this.baseURL + `/campaigns/query`, {\n filter,\n sort,\n ...(options || {}),\n });\n }\n\n /**\n * updateCampaign - Update a Campaign\n *\n * @param {string} id Campaign ID\n * @param {Partial<CampaignData>} params Campaign data\n *\n * @return {Campaign} Updated Campaign\n */\n async updateCampaign(id: string, params: Partial<CampaignData>) {\n this.validateServerSideAuth();\n return this.put<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`, params);\n }\n\n /**\n * deleteCampaign - Delete a Campaign\n *\n * @param {string} id Campaign ID\n *\n * @return {Promise<APIResponse>} The Server Response\n */\n async deleteCampaign(id: string) {\n this.validateServerSideAuth();\n return this.delete<APIResponse>(this.baseURL + `/campaigns/${encodeURIComponent(id)}`);\n }\n\n /**\n * stopCampaign - Stop a Campaign\n *\n * @param {string} id Campaign ID\n *\n * @return {Campaign} Stopped Campaign\n */\n async stopCampaign(id: string) {\n this.validateServerSideAuth();\n return this.post<{ campaign: CampaignResponse }>(this.baseURL + `/campaigns/${encodeURIComponent(id)}/stop`);\n }\n\n /**\n * enrichURL - Get OpenGraph data of the given link\n *\n * @param {string} url link\n * @return {OGAttachment} OG Attachment\n */\n async enrichURL(url: string) {\n return this.get<APIResponse & OGAttachment>(this.baseURL + `/og`, { url });\n }\n\n /**\n * getTask - Gets status of a long running task\n *\n * @param {string} id Task ID\n *\n * @return {TaskStatus} The task status\n */\n async getTask(id: string) {\n return this.get<APIResponse & TaskStatus>(`${this.baseURL}/tasks/${encodeURIComponent(id)}`);\n }\n\n /**\n * deleteChannels - Deletes a list of channel\n *\n * @param {string[]} cids Channel CIDs\n * @param {boolean} [options.hard_delete] Defines if the channel is hard deleted or not\n *\n * @return {DeleteChannelsResponse} Result of the soft deletion, if server-side, it holds the task ID as well\n */\n async deleteChannels(cids: string[], options: { hard_delete?: boolean } = {}) {\n return await this.post<APIResponse & DeleteChannelsResponse>(this.baseURL + `/channels/delete`, {\n cids,\n ...options,\n });\n }\n\n /**\n * deleteUsers - Batch Delete Users\n *\n * @param {string[]} user_ids which users to delete\n * @param {DeleteUserOptions} options Configuration how to delete users\n *\n * @return {TaskResponse} A task ID\n */\n async deleteUsers(user_ids: string[], options: DeleteUserOptions = {}) {\n if (typeof options.user !== 'undefined' && !['soft', 'hard', 'pruning'].includes(options.user)) {\n throw new Error('Invalid delete user options. user must be one of [soft hard pruning]');\n }\n if (typeof options.conversations !== 'undefined' && !['soft', 'hard'].includes(options.conversations)) {\n throw new Error('Invalid delete user options. conversations must be one of [soft hard]');\n }\n if (typeof options.messages !== 'undefined' && !['soft', 'hard', 'pruning'].includes(options.messages)) {\n throw new Error('Invalid delete user options. messages must be one of [soft hard pruning]');\n }\n return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/delete`, {\n user_ids,\n ...options,\n });\n }\n\n /**\n * _createImportURL - Create an Import upload url.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} filename filename of uploaded data\n * @return {APIResponse & CreateImportResponse} An ImportTask\n */\n async _createImportURL(filename: string) {\n return await this.post<APIResponse & CreateImportURLResponse>(this.baseURL + `/import_urls`, {\n filename,\n });\n }\n\n /**\n * _createImport - Create an Import Task.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} path path of uploaded data\n * @param {CreateImportOptions} options import options\n * @return {APIResponse & CreateImportResponse} An ImportTask\n */\n async _createImport(path: string, options: CreateImportOptions = { mode: 'upsert' }) {\n return await this.post<APIResponse & CreateImportResponse>(this.baseURL + `/imports`, {\n path,\n ...options,\n });\n }\n\n /**\n * _getImport - Get an Import Task.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {string} id id of Import Task\n *\n * @return {APIResponse & GetImportResponse} An ImportTask\n */\n async _getImport(id: string) {\n return await this.get<APIResponse & GetImportResponse>(this.baseURL + `/imports/${encodeURIComponent(id)}`);\n }\n\n /**\n * _listImports - Lists Import Tasks.\n *\n * Note: Do not use this.\n * It is present for internal usage only.\n * This function can, and will, break and/or be removed at any point in time.\n *\n * @private\n * @param {ListImportsPaginationOptions} options pagination options\n *\n * @return {APIResponse & ListImportsResponse} An ImportTask\n */\n async _listImports(options: ListImportsPaginationOptions) {\n return await this.get<APIResponse & ListImportsResponse>(this.baseURL + `/imports`, options);\n }\n\n /**\n * upsertPushProvider - Create or Update a push provider\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @param {PushProviderConfig} configuration of the provider you want to create or update\n *\n * @return {APIResponse & PushProviderUpsertResponse} A push provider\n */\n async upsertPushProvider(pushProvider: PushProviderConfig) {\n return await this.post<APIResponse & PushProviderUpsertResponse>(this.baseURL + `/push_providers`, {\n push_provider: pushProvider,\n });\n }\n\n /**\n * deletePushProvider - Delete a push provider\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @param {PushProviderID} type and foreign id of the push provider to be deleted\n *\n * @return {APIResponse} An API response\n */\n async deletePushProvider({ type, name }: PushProviderID) {\n return await this.delete<APIResponse>(\n this.baseURL + `/push_providers/${encodeURIComponent(type)}/${encodeURIComponent(name)}`,\n );\n }\n\n /**\n * listPushProviders - Get all push providers in the app\n *\n * Note: Works only for v2 push version is enabled on app settings.\n *\n * @return {APIResponse & PushProviderListResponse} A push provider\n */\n async listPushProviders() {\n return await this.get<APIResponse & PushProviderListResponse>(this.baseURL + `/push_providers`);\n }\n\n /**\n * creates an abort controller that will be used by the next HTTP Request.\n */\n createAbortControllerForNextRequest() {\n return (this.nextRequestAbortController = new AbortController());\n }\n\n /**\n * commits a pending message, making it visible in the channel and for other users\n * @param id the message id\n *\n * @return {APIResponse & MessageResponse} The message\n */\n async commitMessage(id: string) {\n return await this.post<APIResponse & MessageResponse>(this.baseURL + `/messages/${encodeURIComponent(id)}/commit`);\n }\n\n /**\n * Creates a poll\n * @param poll PollData The poll that will be created\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & CreatePollAPIResponse} The poll\n */\n async createPoll(poll: CreatePollData<StreamChatGenerics>, userId?: string) {\n return await this.post<APIResponse & CreatePollAPIResponse<StreamChatGenerics>>(this.baseURL + `/polls`, {\n ...poll,\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Retrieves a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & GetPollAPIResponse} The poll\n */\n async getPoll(id: string, userId?: string): Promise<APIResponse & GetPollAPIResponse<StreamChatGenerics>> {\n return await this.get<APIResponse & GetPollAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(id)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Updates a poll\n * @param poll PollData The poll that will be updated\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollResponse} The poll\n */\n async updatePoll(poll: PollData<StreamChatGenerics>, userId?: string) {\n return await this.put<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>>(this.baseURL + `/polls`, {\n ...poll,\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Partially updates a poll\n * @param id string The poll id\n * @param {PartialPollUpdate<StreamChatGenerics>} partialPollObject which should contain id and any of \"set\" or \"unset\" params;\n * @param userId string The user id (only serverside)\n * example: {id: \"44f26af5-f2be-4fa7-9dac-71cf893781de\", set:{field: value}, unset:[\"field2\"]}\n * @returns {APIResponse & UpdatePollAPIResponse} The poll\n */\n async partialUpdatePoll(\n id: string,\n partialPollObject: PartialPollUpdate<StreamChatGenerics>,\n userId?: string,\n ): Promise<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>> {\n return await this.patch<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(id)}`,\n {\n ...partialPollObject,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Delete a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns\n */\n async deletePoll(id: string, userId?: string): Promise<APIResponse> {\n return await this.delete<APIResponse>(this.baseURL + `/polls/${encodeURIComponent(id)}`, {\n ...(userId ? { user_id: userId } : {}),\n });\n }\n\n /**\n * Close a poll\n * @param id string The poll id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & UpdatePollAPIResponse} The poll\n */\n async closePoll(id: string, userId?: string): Promise<APIResponse & UpdatePollAPIResponse<StreamChatGenerics>> {\n return this.partialUpdatePoll(\n id,\n {\n set: {\n is_closed: true,\n } as PartialPollUpdate<StreamChatGenerics>['set'],\n },\n userId,\n );\n }\n\n /**\n * Creates a poll option\n * @param pollId string The poll id\n * @param option PollOptionData The poll option that will be created\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollOptionResponse} The poll option\n */\n async createPollOption(pollId: string, option: PollOptionData<StreamChatGenerics>, userId?: string) {\n return await this.post<APIResponse & CreatePollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options`,\n {\n ...option,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Retrieves a poll option\n * @param pollId string The poll id\n * @param optionId string The poll option id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollOptionResponse} The poll option\n */\n async getPollOption(pollId: string, optionId: string, userId?: string) {\n return await this.get<APIResponse & GetPollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options/${encodeURIComponent(optionId)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Updates a poll option\n * @param pollId string The poll id\n * @param option PollOptionData The poll option that will be updated\n * @param userId string The user id (only serverside)\n * @returns\n */\n async updatePollOption(pollId: string, option: PollOptionData<StreamChatGenerics>, userId?: string) {\n return await this.put<APIResponse & UpdatePollOptionAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options`,\n {\n ...option,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Delete a poll option\n * @param pollId string The poll id\n * @param optionId string The poll option id\n * @param userId string The user id (only serverside)\n * @returns {APIResponse} The poll option\n */\n async deletePollOption(pollId: string, optionId: string, userId?: string) {\n return await this.delete<APIResponse>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/options/${encodeURIComponent(optionId)}`,\n userId ? { user_id: userId } : {},\n );\n }\n\n /**\n * Cast vote on a poll\n * @param messageId string The message id\n * @param pollId string The poll id\n * @param vote PollVoteData The vote that will be casted\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & CastVoteAPIResponse} The poll vote\n */\n async castPollVote(messageId: string, pollId: string, vote: PollVoteData, userId?: string) {\n return await this.post<APIResponse & CastVoteAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/messages/${encodeURIComponent(messageId)}/polls/${encodeURIComponent(pollId)}/vote`,\n {\n vote,\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Add a poll answer\n * @param messageId string The message id\n * @param pollId string The poll id\n * @param answerText string The answer text\n * @param userId string The user id (only serverside)\n */\n async addPollAnswer(messageId: string, pollId: string, answerText: string, userId?: string) {\n return this.castPollVote(\n messageId,\n pollId,\n {\n answer_text: answerText,\n },\n userId,\n );\n }\n\n async removePollVote(messageId: string, pollId: string, voteId: string, userId?: string) {\n return await this.delete<APIResponse & { vote: PollVote }>(\n this.baseURL +\n `/messages/${encodeURIComponent(messageId)}/polls/${encodeURIComponent(pollId)}/vote/${encodeURIComponent(\n voteId,\n )}`,\n {\n ...(userId ? { user_id: userId } : {}),\n },\n );\n }\n\n /**\n * Queries polls\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & QueryPollsResponse} The polls\n */\n async queryPolls(\n filter: QueryPollsFilters = {},\n sort: PollSort = [],\n options: QueryPollsOptions = {},\n userId?: string,\n ): Promise<APIResponse & QueryPollsResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & QueryPollsResponse<StreamChatGenerics>>(this.baseURL + `/polls/query${q}`, {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n });\n }\n\n /**\n * Queries poll votes\n * @param pollId\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollVotesAPIResponse} The poll votes\n */\n async queryPollVotes(\n pollId: string,\n filter: QueryVotesFilters = {},\n sort: VoteSort = [],\n options: QueryVotesOptions = {},\n userId?: string,\n ): Promise<APIResponse & PollVotesAPIResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & PollVotesAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/votes${q}`,\n {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * Queries poll answers\n * @param pollId\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10, offset:0}\n * @param userId string The user id (only serverside)\n * @returns {APIResponse & PollAnswersAPIResponse} The poll votes\n */\n async queryPollAnswers(\n pollId: string,\n filter: QueryVotesFilters = {},\n sort: VoteSort = [],\n options: QueryVotesOptions = {},\n userId?: string,\n ): Promise<APIResponse & PollAnswersAPIResponse<StreamChatGenerics>> {\n const q = userId ? `?user_id=${userId}` : '';\n return await this.post<APIResponse & PollAnswersAPIResponse<StreamChatGenerics>>(\n this.baseURL + `/polls/${encodeURIComponent(pollId)}/votes${q}`,\n {\n filter: { ...filter, is_answer: true },\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * Query message history\n * @param filter\n * @param sort\n * @param options Option object, {limit: 10}\n * @returns {APIResponse & QueryMessageHistoryResponse} The message histories\n */\n async queryMessageHistory(\n filter: QueryMessageHistoryFilters = {},\n sort: QueryMessageHistorySort = [],\n options: QueryMessageHistoryOptions = {},\n ): Promise<APIResponse & QueryMessageHistoryResponse<StreamChatGenerics>> {\n return await this.post<APIResponse & QueryMessageHistoryResponse<StreamChatGenerics>>(\n this.baseURL + '/messages/history',\n {\n filter,\n sort: normalizeQuerySort(sort),\n ...options,\n },\n );\n }\n\n /**\n * updateFlags - reviews/unflags flagged message\n *\n * @param {string[]} message_ids list of message IDs\n * @param {string} options Option object in case user ID is set to review all the flagged messages by the user\n * @param {string} reviewed_by user ID who reviewed the flagged message\n * @returns {APIResponse}\n */\n async updateFlags(message_ids: string[], reviewed_by: string, options: { user_id?: string } = {}) {\n return await this.post<APIResponse>(this.baseURL + '/automod/v1/moderation/update_flags', {\n message_ids,\n reviewed_by,\n ...options,\n });\n }\n}\n","export default null;","import { PermissionObject } from './types';\n\ntype RequiredPermissionObject = Required<PermissionObject>;\n\nexport const Allow = 'Allow';\nexport const Deny = 'Deny';\nexport const AnyResource = ['*'];\nexport const AnyRole = ['*'];\nexport const MaxPriority = 999;\nexport const MinPriority = 1;\n\n// deprecated permission object class, you should use the new permission system v2 and use permissions\n// defined in BuiltinPermissions to configure your channel types\n\nexport class Permission {\n name: RequiredPermissionObject['name'];\n action: RequiredPermissionObject['action'];\n owner: RequiredPermissionObject['owner'];\n priority: RequiredPermissionObject['priority'];\n resources: RequiredPermissionObject['resources'];\n roles: RequiredPermissionObject['roles'];\n constructor(\n name: string,\n priority: number,\n resources = AnyResource,\n roles = AnyRole,\n owner = false,\n action: RequiredPermissionObject['action'] = Allow,\n ) {\n this.name = name;\n this.action = action;\n this.owner = owner;\n this.priority = priority;\n this.resources = resources;\n this.roles = roles;\n }\n}\n\n// deprecated\nexport const AllowAll = new Permission('Allow all', MaxPriority, AnyResource, AnyRole, false, Allow);\n\n// deprecated\nexport const DenyAll = new Permission('Deny all', MinPriority, AnyResource, AnyRole, false, Deny);\n\nexport type Role = 'admin' | 'user' | 'guest' | 'anonymous' | 'channel_member' | 'channel_moderator' | string;\n\nexport const BuiltinRoles = {\n Admin: 'admin',\n Anonymous: 'anonymous',\n ChannelMember: 'channel_member',\n ChannelModerator: 'channel_moderator',\n Guest: 'guest',\n User: 'user',\n};\n\nexport const BuiltinPermissions = {\n AddLinks: 'Add Links',\n BanUser: 'Ban User',\n CreateChannel: 'Create Channel',\n CreateMessage: 'Create Message',\n CreateReaction: 'Create Reaction',\n DeleteAnyAttachment: 'Delete Any Attachment',\n DeleteAnyChannel: 'Delete Any Channel',\n DeleteAnyMessage: 'Delete Any Message',\n DeleteAnyReaction: 'Delete Any Reaction',\n DeleteOwnAttachment: 'Delete Own Attachment',\n DeleteOwnChannel: 'Delete Own Channel',\n DeleteOwnMessage: 'Delete Own Message',\n DeleteOwnReaction: 'Delete Own Reaction',\n ReadAnyChannel: 'Read Any Channel',\n ReadOwnChannel: 'Read Own Channel',\n RunMessageAction: 'Run Message Action',\n UpdateAnyChannel: 'Update Any Channel',\n UpdateAnyMessage: 'Update Any Message',\n UpdateMembersAnyChannel: 'Update Members Any Channel',\n UpdateMembersOwnChannel: 'Update Members Own Channel',\n UpdateOwnChannel: 'Update Own Channel',\n UpdateOwnMessage: 'Update Own Message',\n UploadAttachment: 'Upload Attachment',\n UseFrozenChannel: 'Send messages and reactions to frozen channels',\n};\n","export const EVENT_MAP = {\n 'channel.created': true,\n 'channel.deleted': true,\n 'channel.hidden': true,\n 'channel.kicked': true,\n 'channel.muted': true,\n 'channel.truncated': true,\n 'channel.unmuted': true,\n 'channel.updated': true,\n 'channel.visible': true,\n 'health.check': true,\n 'member.added': true,\n 'member.removed': true,\n 'member.updated': true,\n 'message.deleted': true,\n 'message.new': true,\n 'message.read': true,\n 'message.updated': true,\n 'message.undeleted': true,\n 'notification.added_to_channel': true,\n 'notification.channel_deleted': true,\n 'notification.channel_mutes_updated': true,\n 'notification.channel_truncated': true,\n 'notification.invite_accepted': true,\n 'notification.invite_rejected': true,\n 'notification.invited': true,\n 'notification.mark_read': true,\n 'notification.mark_unread': true,\n 'notification.message_new': true,\n 'notification.mutes_updated': true,\n 'notification.removed_from_channel': true,\n 'notification.thread_message_new': true,\n 'poll.closed': true,\n 'poll.updated': true,\n 'poll.vote_casted': true,\n 'poll.vote_changed': true,\n 'poll.vote_removed': true,\n 'reaction.deleted': true,\n 'reaction.new': true,\n 'reaction.updated': true,\n 'typing.start': true,\n 'typing.stop': true,\n 'user.banned': true,\n 'user.deleted': true,\n 'user.presence.changed': true,\n 'user.unbanned': true,\n 'user.unread_message_reminder': true,\n 'user.updated': true,\n 'user.watching.start': true,\n 'user.watching.stop': true,\n\n // local events\n 'channels.queried': true,\n 'connection.changed': true,\n 'connection.recovered': true,\n 'transport.changed': true,\n 'capabilities.changed': true,\n};\n"],"names":["uint8","tmp","len","length","extraBytes","parts","maxChunkLength","i","len2","push","encodeChunk","lookup","join","revLookup","code","charCodeAt","start","end","num","output","isString","arrayOrString","isMapStringCallback","callback","encodeBase64","data","fromByteArray","Uint8Array","res","k","charAt","mappedValue","map","char","decodeBase64","s","x","a","e","w","String","fromCharCode","L","b","l","r","asyncGeneratorStep","gen","resolve","reject","_next","_throw","key","arg","info","value","error","done","Promise","then","_asyncToGenerator","fn","self","this","args","arguments","apply","err","undefined","_classCallCheck","instance","Constructor","TypeError","_defineProperties","target","props","descriptor","enumerable","configurable","writable","Object","defineProperty","_createClass","protoProps","staticProps","prototype","_defineProperty","obj","runtime","exports","Op","hasOwn","hasOwnProperty","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","define","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","state","GenStateSuspendedStart","method","GenStateExecuting","Error","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","type","GenStateSuspendedYield","makeInvokeMethod","call","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","defineIteratorMethods","forEach","AsyncIterator","PromiseImpl","invoke","result","__await","unwrapped","previousPromise","callInvokeWithMethodAndArg","resultName","next","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","constructor","displayName","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","async","iter","toString","keys","object","reverse","pop","skipTempReset","prev","slice","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","catch","thrown","delegateYield","module","regeneratorRuntime","accidentalStrictMode","Function","require$$0","Campaign","client","id","body","message_template","_this$data","segment_ids","_this$data2","sender_id","_this$data3","channel_template","_this$data4","create_channels","_this$data5","description","_this$data6","_this$data7","user_ids","_this$data8","createCampaign","campaign","options","verifyCampaignId","startCampaign","updateCampaign","deleteCampaign","stopCampaign","getCampaign","_extends","assign","source","_typeof","_objectWithoutProperties","excluded","sourceKeys","indexOf","objectWithoutPropertiesLoose","getOwnPropertySymbols","sourceSymbolKeys","propertyIsEnumerable","_arrayLikeToArray","arr","arr2","Array","_unsupportedIterableToArray","o","minLen","arrayLikeToArray","n","from","test","_toConsumableArray","isArray","arrayWithoutHoles","iterableToArray","unsupportedIterableToArray","nonIterableSpread","bind","thisArg","kindOf","cache","thing","str","toLowerCase","kindOfTest","typeOfTest","isUndefined","isArrayBuffer","isFunction","isNumber","isObject","isPlainObject","val","isDate","isFile","isBlob","isFileList","isURLSearchParams","allOwnKeys","getOwnPropertyNames","findKey","_key","_global","globalThis","window","global","isContextDefined","isTypedArray","TypedArray","isHTMLForm","prop","isRegExp","reduceDescriptors","reducer","descriptors","getOwnPropertyDescriptors","reducedDescriptors","ret","defineProperties","ALPHA","DIGIT","ALPHABET","ALPHA_DIGIT","toUpperCase","isAsyncFn","isBuffer","isFormData","kind","FormData","append","isArrayBufferView","ArrayBuffer","isView","buffer","isBoolean","isStream","pipe","merge","caseless","assignValue","targetKey","extend","trim","replace","stripBOM","content","inherits","superConstructor","toFlatObject","sourceObj","destObj","filter","propFilter","merged","endsWith","searchString","position","lastIndex","toArray","forEachEntry","pair","matchAll","regExp","matches","exec","hasOwnProp","freezeMethods","set","toObjectSet","delimiter","split","toCamelCase","m","p1","p2","noop","toFiniteNumber","defaultValue","Number","isFinite","generateString","size","alphabet","Math","random","isSpecCompliantForm","toJSONObject","stack","visit","reducedValue","isThenable","AxiosError","message","config","request","response","captureStackTrace","utils","toJSON","number","fileName","lineNumber","columnNumber","status","customProps","axiosError","cause","isVisitable","removeBrackets","renderKey","path","dots","concat","token","predicates","toFormData","formData","metaTokens","indexes","option","visitor","defaultVisitor","useBlob","Blob","convertValue","toISOString","Buffer","JSON","stringify","some","isFlatArray","el","index","exposedHelpers","build","encode","charMap","encodeURIComponent","match","AxiosURLSearchParams","params","_pairs","buildURL","url","_encode","serializeFn","serialize","serializedParams","hashmarkIndex","encoder","InterceptorManager","handlers","use","fulfilled","rejected","synchronous","runWhen","eject","clear","h","silentJSONParsing","forcedJSONParsing","clarifyTimeoutError","isBrowser","classes","URLSearchParams","isStandardBrowserEnv","product","navigator","document","isStandardBrowserWebWorkerEnv","WorkerGlobalScope","importScripts","protocols","formDataToJSON","buildPath","isNumericKey","isLast","arrayToObject","entries","parsePropPath","defaults","transitional","transitionalDefaults","adapter","transformRequest","headers","contentType","getContentType","hasJSONContentType","isObjectPayload","setContentType","platform","helpers","toURLEncodedForm","formSerializer","_FormData","env","rawValue","parser","parse","stringifySafely","transformResponse","JSONRequested","responseType","strictJSONParsing","ERR_BAD_RESPONSE","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","common","Accept","ignoreDuplicateOf","$internals","normalizeHeader","header","normalizeValue","matchHeaderValue","isHeaderNameFilter","AxiosHeaders","valueOrRewrite","rewrite","setHeader","_value","_header","_rewrite","lHeader","setHeaders","rawHeaders","parsed","line","substring","parseHeaders","get","tokens","tokensRE","parseTokens","has","matcher","delete","deleted","deleteHeader","normalize","format","normalized","formatHeader","targets","asStrings","static","first","computed","accessors","defineAccessor","accessorName","methodName","arg1","arg2","arg3","buildAccessors","transformData","fns","isCancel","__CANCEL__","CanceledError","ERR_CANCELED","accessor","mapped","headerValue","write","expires","domain","secure","cookie","Date","toGMTString","read","RegExp","decodeURIComponent","remove","now","buildFullPath","baseURL","requestedURL","relativeURL","combineURLs","msie","userAgent","urlParsingNode","createElement","originURL","resolveURL","href","setAttribute","protocol","host","search","hash","hostname","port","pathname","location","requestURL","progressEventReducer","listener","isDownloadStream","bytesNotified","_speedometer","samplesCount","min","bytes","timestamps","firstSampleTS","head","tail","chunkLength","startedAt","bytesCount","passed","round","speedometer","loaded","total","lengthComputable","progressBytes","rate","progress","estimated","event","knownAdapters","http","xhr","XMLHttpRequest","requestData","requestHeaders","onCanceled","cancelToken","unsubscribe","signal","removeEventListener","auth","username","password","unescape","btoa","fullPath","onloadend","responseHeaders","getAllResponseHeaders","ERR_BAD_REQUEST","floor","settle","responseText","statusText","open","paramsSerializer","onreadystatechange","readyState","responseURL","setTimeout","onabort","ECONNABORTED","onerror","ERR_NETWORK","ontimeout","timeoutErrorMessage","ETIMEDOUT","xsrfValue","isURLSameOrigin","cookies","setRequestHeader","withCredentials","onDownloadProgress","addEventListener","onUploadProgress","upload","cancel","abort","subscribe","aborted","parseProtocol","send","renderReason","reason","isResolvedHandle","adapters","nameOrAdapter","rejectedReasons","reasons","throwIfCancellationRequested","throwIfRequested","dispatchRequest","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","timeoutMessage","decompress","beforeRedirect","transport","httpAgent","httpsAgent","socketPath","responseEncoding","configValue","VERSION","validators","deprecatedWarnings","validator","version","formatMessage","opt","desc","opts","ERR_DEPRECATED","console","warn","assertOptions","schema","allowUnknown","ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","Axios","instanceConfig","interceptors","configOrUrl","boolean","function","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","interceptor","unshift","responseInterceptorChain","promise","chain","newConfig","onFulfilled","onRejected","getUri","generateHTTPMethod","isForm","CancelToken","executor","resolvePromise","_listeners","onfulfilled","_resolve","splice","c","HttpStatusCode","Continue","SwitchingProtocols","Processing","EarlyHints","Ok","Created","Accepted","NonAuthoritativeInformation","NoContent","ResetContent","PartialContent","MultiStatus","AlreadyReported","ImUsed","MultipleChoices","MovedPermanently","Found","SeeOther","NotModified","UseProxy","Unused","TemporaryRedirect","PermanentRedirect","BadRequest","Unauthorized","PaymentRequired","Forbidden","NotFound","MethodNotAllowed","NotAcceptable","ProxyAuthenticationRequired","RequestTimeout","Conflict","Gone","LengthRequired","PreconditionFailed","PayloadTooLarge","UriTooLong","UnsupportedMediaType","RangeNotSatisfiable","ExpectationFailed","ImATeapot","MisdirectedRequest","UnprocessableEntity","Locked","FailedDependency","TooEarly","UpgradeRequired","PreconditionRequired","TooManyRequests","RequestHeaderFieldsTooLarge","UnavailableForLegalReasons","InternalServerError","NotImplemented","BadGateway","ServiceUnavailable","GatewayTimeout","HttpVersionNotSupported","VariantAlsoNegotiates","InsufficientStorage","LoopDetected","NotExtended","NetworkAuthenticationRequired","axios","createInstance","defaultConfig","Cancel","all","promises","spread","isAxiosError","payload","formToJSON","getAdapter","default","_slicedToArray","arrayWithHoles","_i","_s","_e","_arr","_n","_d","iterableToArrayLimit","nonIterableRest","logChatPromiseExecution","sleep","chatCodes","TOKEN_EXPIRED","WS_CLOSED_SUCCESS","addFileToFormData","uri","readable","_read","File","isFileWebAPI","isBlobWebAPI","normalizeQuerySort","sort","sortFields","item","field","direction","retryInterval","numberOfFailures","max","randomId","getRandomValues","getRandomBytes","hex","subarray","padStart","getRandomValuesWithMathRandom","pow","byteLength","crypto","_crypto","msCrypto","convertErrorToJson","jsonObj","getOwnPropertyDescriptor","_","addConnectionEventListeners","cb","removeConnectionEventListeners","axiosParamsSerializer","newParams","__html","html","pinned_at","created_at","updated_at","deleted_at","reaction_groups","maybeGetReactionGroupsFallback","reaction_counts","reaction_scores","findIndexInSortedArray","needle","sortedArray","selectValueToCompare","sortDirection","left","right","middle","comparableNeedle","comparableMiddle","addToMessageList","messages","newMessage","timestampChanged","sortBy","addIfDoesNotExist","addMessageToList","newMessages","messageTime","getTime","messageIsNewest","at","insertionIndex","groups","counts","scores","fallback","count","sum_scores","throttle","leading","trailing","runningTimeout","storedArgs","timeoutHandler","messagePaginationCreatedAtAround","hasPrev","hasNext","updateHasPrev","updateHasNext","parentSet","requestedPageSize","returnedPage","messagePaginationOptions","newPagination","pagination","created_at_around","createdAtAroundDate","firstPageMsg","lastPageMsg","wholePageHasNewerMessages","wholePageHasOlderMessages","requestedPageSizeNotMet","noMoreMessages","_parentSet$messages$","_parentSet$messages$s","midPointByCount","midPointByCreationDate","array","targetDate","mid","midCreatedAt","midDate","binarySearchByDateEqualOrNearestGreater","messageSetPagination","logger","_params$messagePagina","_params$messagePagina2","id_around","_parentSet$messages$2","_parentSet$messages$s2","midPoint","targetMsg","halves","find","messagePaginationIdAround","firstPageMsgIsFirstInSet","_parentSet$messages$3","lastPageMsgIsLastInSet","_parentSet$messages$s3","queriedNextMessages","created_at_after_or_equal","created_at_after","id_gt","id_gte","queriedPrevMessages","created_at_before_or_equal","created_at_before","id_lt","id_lte","offset","containsUnrecognizedOptionsOnly","hasMore","returnedPageIsEmpty","messagePaginationLinear","DEFAULT_MESSAGE_SET_PAGINATION","ChannelState","channel","isUpToDate","_this","msgArray","msg","removed","user","_updateUserMessages","parentId","messageSets","threads","pinnedMessages","hardDelete","_deleteUserMessages","cid","latest_reactions","mentioned_users","own_reactions","parent_id","reply_count","thread_participants","_channel","watcher_count","typing","initMessages","pending_messages","mutedUsers","watchers","members","membership","unreadCount","last_message_at","isCurrent","findIndex","isLatest","messageSetToAddToIfDoesNotExist","addMessagesSorted","initializing","findTargetMessageSet","messagesToAdd","targetMessageSetIndex","isFromShadowBannedUser","shadowed","isMessageFormatted","_this$_channel","getClient","updateUserReference","parentID","show_in_channel","_addToMessageList","thread","messageSet","addPinnedMessage","pinnedMessage","removeMessageFromArray","reaction","enforce_unique","messageWithReaction","_updateMessage","_this2","_addOwnReactionToMessage","ownReactions","_removeOwnReactionFromMessage","userID","user_id","_this3","update","updatedMessages","reduce","acc","quoted_message_id","_m$pinned_at","_m$updated_at","quoted_message","attachments","_this4","_updateQuotedMessageReferences","updateFunc","pinned","msgIndex","messageSetIndex","findMessageSetIndex","messageToRemove","isRemoved","threadMessages","filteredMessages","latestMessages","lastEvent","receivedAt","received_at","dispatchEvent","messageId","parentMessageId","limit","switchedToMessageSet","loadedMessageThread","messageIdToFind","switchToMessageSet","_this$threads$parentM","query","getReplies","currentMessages","messages1","messages2","m1","m2","overlappingMessageSetIndices","_this5","areMessageSetsOverlap","mergeTargetMessageSetIndex","mergeSourceMessageSetIndices","sources","overlappingMessageSetIndex","Channel","defaultOptions","watch","presence","listeners","_client","_data","initialized","offlineMode","lastTypingEvent","isTyping","disconnected","configs","post","_channelURL","sendFile","_checkInitialized","filter_conditions","message_filter_conditions","wsPromise","filterConditions","updates","patch","messageID","reactionType","channelData","updateMessage","_update","areCapabilitiesChanged","own_capabilities","coolDownInterval","cooldown","accept_invite","reject_invite","add_members","add_moderators","roles","assign_roles","invites","remove_members","demote_moderators","channel_cid","cli","uid","partialUpdateMember","archived","resp","channel_member","_muteStatus","message_id","form_data","_isTypingIndicatorsEnabled","diff","lastKeyStroke","sendEvent","getConfig","_this$getConfig","typing_events","_this$getClient$user","privacy_settings","_this$getClient$user$2","typing_indicators","_this$getClient$user$3","enabled","messageSlice","_this$getConfig2","read_events","_isUsingServerAuth","_this$getConfig3","stopTyping","clean","_hasConnectionID","combined","tags","normalizedSort","messageIds","ids","last_read","silent","userMuteStatus","includes","muteStatus","muted","lastRead","_countMessageAsUnread","_message$mentioned_us","queryURL","membersStr","member","_member$user","tempChannelCid","activeChannels","_addChannelConfig","_initializeState","_options$messages","polls","hydratePollCache","queriedChannels","channels","isLatestMessageSet","targetUserID","banUser","userId","clearHistory","clear_history","unbanUser","shadowBan","removeShadowBan","pollId","vote","castPollVote","voteId","removePollVote","callbackOrString","callbackOrNothing","channelState","_event$user","_event$user2","last_read_message_id","unread_messages","_this$getClient$user2","_event$user5","_event$user6","_extendEventWithOwnReactions","hard_delete","removeMessage","addMessageSorted","removeQuotedMessageReferences","removePinnedMessage","ownMessage","_this$getClient$user3","isThreadMessage","_event$user8","_event$channel","truncated_at","truncatedAt","createdAt","clearMessages","_event$member","_event$user9","newMembers","_this$getClient$user4","first_unread_message_id","last_read_at","frozen","_channel$data","hidden","_event$channel3","_channel$data2","_event$channel4","_channel$data3","addReaction","removeReaction","_event$user11","shadow_banned","shadow","banned","_event$user12","clientState","addPinnedMessages","pinned_messages","watcher","_hydrateMembers","findMessage","setIsUpToDate","ClientState","users","userChannelReferences","updateUser","channelID","ws","WebSocket","MozWebSocket","InsightMetrics","connectionStartTimestamp","wsTotalFailures","wsConsecutiveFailures","instanceClientId","postInsights","insightType","insights","maxAttempts","buildWsFatalInsight","connection","buildWsBaseInsight","ready_state","_connection$ws","_buildUrl","api_key","start_ts","insightMetrics","end_ts","auth_type","getAuthType","tokenManager","user_details","_user","device","client_id","connectionID","ws_details","ws_consecutive_failures","ws_total_failures","request_id","requestID","online","_navigator","onLine","user_agent","_navigator2","instance_client_id","buildWsSuccessAfterFailureInsight","isCloseEvent","isErrorEvent","StableWSConnection","qs","_buildWSPayload","getToken","wsBaseURL","getUserAgent","_log","_setHealth","isHealthy","_reconnect","interval","wsID","isResolved","rejectPromise","_errorFromWSEvent","scheduleNextPing","handleEvent","scheduleConnectionCheck","wasClean","consecutiveFailures","totalFailures","isConnecting","healthy","statusCode","isWSFailure","StatusCode","connectionOpen","healthCheckTimeoutRef","clearTimeout","clientID","pingInterval","connectionCheckTimeoutRef","connectionCheckTimeout","isDisconnected","onlineStatusChanged","extra","level","_connect","healthCheck","_context","isStatic","refreshToken","_waitForHealthy","race","_context2","isClosedPromise","clearInterval","removeAllListeners","close","OPEN","onclose","enableWSFallback","isTokenReady","tokenReady","loadToken","_setupConnectionPromise","wsURL","onopen","onmessage","connection_id","enableInsights","_destroyCurrentWSConnection","recoverState","_context6","JWTUserToken","apiSecret","extraData","JWTServerToken","jwtOptions","server","algorithm","noTimestamp","sign","UserFromToken","fragments","b64Payload","DevToken","CheckSignature","secret","signature","createHmac","digest","timingSafeEqual","ConnectionState","TokenManager","tokenOrProvider","validateToken","tokenProvider","loadTokenPromise","anon","tokenUserId","APIErrorCodes","retryable","isAPIError","isErrorRetryable","WSConnectionFallback","_setState","Closed","connect","retry","doAxiosRequest","_this$cancelToken2","_req","Connected","events","_data$events","Disconnected","reconnect","Connecting","json","_poll","_onlineStatusChanged","Init","Segment","all_sender_channels","all_users","createSegment","verifySegmentId","getSegment","updateSegment","addSegmentTargets","removeSegmentTargets","deleteSegment","targetId","segmentTargetExists","querySegmentTargets","_assertThisInitialized","ReferenceError","_setPrototypeOf","p","_possibleConstructorReturn","assertThisInitialized","_getPrototypeOf","_isNativeReflectConstruct","Reflect","construct","sham","Proxy","Boolean","valueOf","_construct","Parent","Class","isNativeReflectConstruct","_wrapNativeSuper","_cache","Map","isNativeFunction","Wrapper","VotingVisibility","ErrorFromResponse","subClass","superClass","StateStore","Set","newValueOrPatch","newValue","isPatch","oldValue","handlerSet","handler","partial","current","add","selector","selectedValues","nextValue","newlySelectedValues","hasUpdatedValues","logCount","oldSelectedValues","DEFAULT_PAGE_LIMIT","DEFAULT_SORT","Thread","threadData","partialNext","active","getLatestValue","isLoading","getThread","hydrateState","replyCount","replies","parentMessage","participants","deletedAt","updatedAt","pendingReplies","failedRepliesMap","isStateStale","unsubscribeFunctions","subscribeMarkActiveThreadRead","subscribeReloadActiveStaleThread","subscribeMarkThreadStale","subscribeNewReplies","subscribeRepliesRead","subscribeMessageDeleted","subscribeMessageUpdated","subscribeWithSelector","unreadMessageCount","ownUnreadCountSelector","throttledMarkAsRead","reload","on","isOwnMessage","upsertReplyLocally","nextRead","userRead","nextUserRead","lastReadAt","parent_message_id","lastReadMessageId","deleteReplyLocally","updateParentMessageLocally","eventType","updateParentMessageOrReplyLocally","cleanupFunction","reply","actualIndex","updatedReplies","formattedMessage","force","ownUnreadCount","markRead","thread_id","markAsRead","otherOptions","loadPage","loadingKey","cursorKey","insertionMethodKey","queryOptions","abs","queryReplies","maybeNextCursor","_replies$at","nextReplies","_context3","placeholderReadResponse","repliesPaginationFromInitialThread","parent_message","formatReadState","latest_replies","nextCursor","prevCursor","_thread$latest_replie2","isLoadingNext","isLoadingPrev","currentUserId","_state$read$currentUs","MODERATION_ENTITY_TYPES","Moderation","flaggedUserID","flag","entityType","entityId","entityCreatorID","entity_type","entity_id","entity_creator_id","targetID","target_ids","actionType","itemID","action_type","item_id","entityID","moderationPayload","configKey","moderation_payload","config_key","THREAD_MANAGER_INITIAL_STATE","isThreadOrderStale","unreadThreadCount","unseenThreadIds","lastConnectionDropAt","ready","ThreadManager","subscribeUnreadThreadsCountChange","subscribeManageThreadSubscriptions","subscribeReloadOnActivation","subscribeRecoverAfterConnectionDrop","subscribeChannelDeleted","unread_threads","me","newThreads","nextThreads","removedThreads","threadsById","registerSubscriptions","unregisterSubscriptions","_event$message","unsubscribeConnectionDropped","throttledHandleConnectionRecovered","unsubscribeConnectionRecovered","queryThreads","currentThreads","incomingThread","existingThread","hasStaleState","participant_limit","reply_limit","threadsByIdGetterCache","newThreadsById","isVoteAnswer","answer_text","Poll","poll","own_votes","pollResponseForState","voteOrAnswer","ownAnswer","ownVotes","lastActivityAt","maxVotedOptionIds","getMaxVotedOptionIds","vote_counts_by_option","ownVotesByOptionId","getOwnVotesByOptionId","getInitialStateFromPollResponse","pollData","extractPollData","is_closed","currentState","isOwnVote","poll_vote","latestAnswers","latest_answers","option_id","pollEnrichData","extractPollEnrichedData","answer","enforce_unique_votes","optionId","getPoll","updatePoll","partialPollObject","partialUpdatePoll","closePoll","deletePoll","createPollOption","updatePollOption","deletePollOption","max_votes_allowed","oldestVote","_oldestVote","_oldestVote2","removeVote","answerText","addPollAnswer","answerId","queryPollAnswers","queryPollVotes","voteCountsByOption","maxVotes","winningOptions","pollResponse","allow_answers","allow_user_suggested_options","enforce_unique_vote","voting_visibility","answers_count","latest_votes_by_option","vote_count","PollManager","pollCache","subscribeMessageNew","subscribePollUpdated","subscribePollClosed","subscribeVoteCasted","subscribeVoteChanged","subscribeVoteRemoved","createPoll","createdPoll","cachedPoll","fromState","setOrOverwriteInCache","queryPolls","pollInstances","overwriteState","pollFromCache","reinitializeState","_event$poll","handlePollUpdated","_event$poll2","handlePollClosed","_event$poll3","handleVoteCasted","_event$poll4","handleVoteChanged","_event$poll5","handleVoteRemoved","StreamChat","secretOrOptions","wsConnection","wsFallback","_this$wsFallback","_getConnectionID","userTokenOrProvider","setUserPromise","node","allowServerSideConnect","anonymous","setTokenPromise","_setToken","_setUser","openConnection","persistUserOnConnectionFailure","closeConnection","disconnectUser","connectUser","setTokenOrProvider","cleaningIntervalRef","_this$wsConnection2","disconnect","_this$wsFallback2","_this$wsFallback3","_startCleaning","before","closePromise","_disconnect","resetState","anonymousUser","_setupConnection","connectAnonymousUser","requestConfig","_enrichAxiosOptions","_logApiRequest","axiosInstance","postForm","put","_logApiResponse","handleResponse","client_request_id","_requestConfig$header","_logApiError","_context5","postListenerCallbacks","_handleClientEvent","_handleChannelEvent","_callClientListeners","_callChannelListeners","messageEvent","jsonString","refMap","_updateMemberWatcherReferences","updateUserMessages","deleteUserMessages","channel_mutes","devices","mutes","total_unread_count","unread_channels","unread_count","invisible","_updateUserMessageReferences","mark_messages_deleted","_deleteUserMessageReference","cids","recoverStateOnReconnect","queryChannels","$in","channelType","custom","tempCid","upsertUsers","upsertUser","unblockMessage","markChannelsRead","mutedChannels","moderation","inputOptions","browser","warmUp","Agent","keepAlive","keepAliveMsecs","setBaseURL","process","STREAM_LOCAL_TEST_RUN","STREAM_LOCAL_TEST_HOST","_this$options","defaultWSTimeoutWithFallback","defaultWSTimeout","apn_config","p12_cert","updateAppSettings","revoke_tokens_issued_before","_normalizeDate","revokeUsersToken","userIDs","partialUpdateUsers","apnTemplate","apn_template","firebaseTemplate","firebase_template","firebaseDataTemplate","firebase_data_template","skipDevices","skip_devices","pushProviderName","push_provider_name","pushProviderType","push_provider_type","last_active","guestUser","access_token","exp","iat","getHeaders","Infinity","errorFromResponse","_handleUserEvent","_event$me","_event$me2","activeChannelKey","deleteAllChannelReference","mute","expiresAt","_sayHi","setClient","nav","mode","updateUsers","stateOptions","hydrateActiveChannels","channelsFromApi","queryChannelsOptions","skipInitialization","updatedMessagesSet","message_limit","_this$wsFallback4","push_provider","serverSide","web","android","ios","endpoints","server_side","channelIDOrCustom","getChannelByMembers","_custom$members","getChannelById","partialUserObject","userMap","userObject","target_user_id","blockedUserID","blocked_user_id","target_id","currentUserID","targetMessageID","target_message_id","callID","reviewResult","review_result","commands","language","timeoutOrExpirationDate","pinExpires","setSeconds","getSeconds","messageOrMessageId","errorText","pinnedBy","pinnedAt","_validateAndGetMessageId","partialUpdateMessage","pin_expires","_normalizeExpiration","clonedMessage","mu","partialMessageObject","hard","undeleted_by","partialThreadObject","reservedThreadFields","unset","_getToken","authorization","Authorization","nextRequestAbortController","_options$headers","axiosRequestConfig","axiosRequestConfigParams","axiosRequestConfigHeaders","axiosRequestConfigRest","that","setInterval","requestBody","xSignature","permissionData","channel_cids","last_sync_at","blockList","exportChannels","idOrData","validateServerSideAuth","segmentId","scheduled_for","scheduledFor","stop_at","stopAt","conversations","filename","pushProvider","AbortController","q","is_answer","message_ids","reviewed_by","_instance","Allow","Deny","AnyResource","AnyRole","Permission","priority","resources","owner","action","AllowAll","DenyAll","AddLinks","BanUser","CreateChannel","CreateMessage","CreateReaction","DeleteAnyAttachment","DeleteAnyChannel","DeleteAnyMessage","DeleteAnyReaction","DeleteOwnAttachment","DeleteOwnChannel","DeleteOwnMessage","DeleteOwnReaction","ReadAnyChannel","ReadOwnChannel","RunMessageAction","UpdateAnyChannel","UpdateAnyMessage","UpdateMembersAnyChannel","UpdateMembersOwnChannel","UpdateOwnChannel","UpdateOwnMessage","UploadAttachment","UseFrozenChannel","Admin","Anonymous","ChannelMember","ChannelModerator","Guest","User"],"mappings":"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"}