stream-chat 4.4.3-dev.3 → 5.0.1

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.
Files changed (53) hide show
  1. package/README.md +4 -13
  2. package/dist/browser.es.js +1258 -722
  3. package/dist/browser.es.js.map +1 -1
  4. package/dist/browser.full-bundle.min.js +1 -1
  5. package/dist/browser.full-bundle.min.js.map +1 -1
  6. package/dist/browser.js +1258 -721
  7. package/dist/browser.js.map +1 -1
  8. package/dist/index.es.js +1258 -722
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/index.js +1258 -721
  11. package/dist/index.js.map +1 -1
  12. package/dist/types/base64.d.ts.map +1 -1
  13. package/dist/types/channel.d.ts +19 -15
  14. package/dist/types/channel.d.ts.map +1 -1
  15. package/dist/types/channel_state.d.ts +2 -2
  16. package/dist/types/channel_state.d.ts.map +1 -1
  17. package/dist/types/client.d.ts +25 -42
  18. package/dist/types/client.d.ts.map +1 -1
  19. package/dist/types/client_state.d.ts +2 -2
  20. package/dist/types/client_state.d.ts.map +1 -1
  21. package/dist/types/connection.d.ts +14 -49
  22. package/dist/types/connection.d.ts.map +1 -1
  23. package/dist/types/connection_fallback.d.ts +41 -0
  24. package/dist/types/connection_fallback.d.ts.map +1 -0
  25. package/dist/types/errors.d.ts +14 -0
  26. package/dist/types/errors.d.ts.map +1 -0
  27. package/dist/types/insights.d.ts +16 -9
  28. package/dist/types/insights.d.ts.map +1 -1
  29. package/dist/types/permissions.d.ts.map +1 -1
  30. package/dist/types/signing.d.ts +3 -3
  31. package/dist/types/signing.d.ts.map +1 -1
  32. package/dist/types/token_manager.d.ts +2 -2
  33. package/dist/types/token_manager.d.ts.map +1 -1
  34. package/dist/types/types.d.ts +95 -89
  35. package/dist/types/types.d.ts.map +1 -1
  36. package/dist/types/utils.d.ts +13 -3
  37. package/dist/types/utils.d.ts.map +1 -1
  38. package/package.json +4 -4
  39. package/src/base64.ts +1 -4
  40. package/src/channel.ts +133 -461
  41. package/src/channel_state.ts +31 -158
  42. package/src/client.ts +298 -712
  43. package/src/client_state.ts +2 -2
  44. package/src/connection.ts +146 -395
  45. package/src/connection_fallback.ts +209 -0
  46. package/src/errors.ts +58 -0
  47. package/src/insights.ts +37 -31
  48. package/src/permissions.ts +3 -24
  49. package/src/signing.ts +6 -17
  50. package/src/token_manager.ts +6 -18
  51. package/src/types.ts +269 -512
  52. package/src/utils.ts +58 -24
  53. package/CHANGELOG.md +0 -844
package/src/client.ts CHANGED
@@ -11,6 +11,8 @@ import { StableWSConnection } from './connection';
11
11
  import { isValidEventType } from './events';
12
12
  import { JWTUserToken, DevToken, CheckSignature } from './signing';
13
13
  import { TokenManager } from './token_manager';
14
+ import { WSConnectionFallback } from './connection_fallback';
15
+ import { isWSFailure } from './errors';
14
16
  import {
15
17
  isFunction,
16
18
  isOwnUserBaseProperty,
@@ -20,6 +22,7 @@ import {
20
22
  randomId,
21
23
  sleep,
22
24
  retryInterval,
25
+ isOnline,
23
26
  } from './utils';
24
27
 
25
28
  import {
@@ -45,7 +48,6 @@ import {
45
48
  CheckSQSResponse,
46
49
  Configs,
47
50
  ConnectAPIResponse,
48
- ConnectionChangeEvent,
49
51
  CreateChannelOptions,
50
52
  CreateChannelResponse,
51
53
  CreateCommandOptions,
@@ -95,7 +97,7 @@ import {
95
97
  TestSQSDataInput,
96
98
  TokenOrProvider,
97
99
  UnBanUserOptions,
98
- UnknownType,
100
+ UR,
99
101
  UpdateChannelOptions,
100
102
  UpdateChannelResponse,
101
103
  UpdateCommandOptions,
@@ -117,35 +119,28 @@ import {
117
119
  DeleteUserOptions,
118
120
  DeleteChannelsResponse,
119
121
  TaskResponse,
122
+ ReservedMessageFields,
120
123
  } from './types';
121
- import { InsightTypes, InsightMetrics } from './insights';
124
+ import { InsightMetrics, postInsights } from './insights';
122
125
 
123
126
  function isString(x: unknown): x is string {
124
127
  return typeof x === 'string' || x instanceof String;
125
128
  }
126
129
 
127
130
  export class StreamChat<
128
- AttachmentType extends UnknownType = UnknownType,
129
- ChannelType extends UnknownType = UnknownType,
131
+ AttachmentType extends UR = UR,
132
+ ChannelType extends UR = UR,
130
133
  CommandType extends string = LiteralStringForUnion,
131
- EventType extends UnknownType = UnknownType,
132
- MessageType extends UnknownType = UnknownType,
133
- ReactionType extends UnknownType = UnknownType,
134
- UserType extends UnknownType = UnknownType
134
+ EventType extends UR = UR,
135
+ MessageType extends UR = UR,
136
+ ReactionType extends UR = UR,
137
+ UserType extends UR = UR
135
138
  > {
136
139
  private static _instance?: unknown | StreamChat; // type is undefined|StreamChat, unknown is due to TS limitations with statics
137
140
 
138
141
  _user?: OwnUserResponse<ChannelType, CommandType, UserType> | UserResponse<UserType>;
139
142
  activeChannels: {
140
- [key: string]: Channel<
141
- AttachmentType,
142
- ChannelType,
143
- CommandType,
144
- EventType,
145
- MessageType,
146
- ReactionType,
147
- UserType
148
- >;
143
+ [key: string]: Channel<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
149
144
  };
150
145
  anonymous: boolean;
151
146
  axiosInstance: AxiosInstance;
@@ -154,22 +149,10 @@ export class StreamChat<
154
149
  cleaningIntervalRef?: NodeJS.Timeout;
155
150
  clientID?: string;
156
151
  configs: Configs<CommandType>;
157
- connectionID?: string;
158
- failures?: number;
159
152
  key: string;
160
153
  listeners: {
161
154
  [key: string]: Array<
162
- (
163
- event: Event<
164
- AttachmentType,
165
- ChannelType,
166
- CommandType,
167
- EventType,
168
- MessageType,
169
- ReactionType,
170
- UserType
171
- >,
172
- ) => void
155
+ (event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>) => void
173
156
  >;
174
157
  };
175
158
  logger: Logger;
@@ -195,10 +178,29 @@ export class StreamChat<
195
178
  userAgent?: string;
196
179
  userID?: string;
197
180
  wsBaseURL?: string;
198
- wsConnection: StableWSConnection<ChannelType, CommandType, UserType> | null;
181
+ wsConnection: StableWSConnection<
182
+ ChannelType,
183
+ CommandType,
184
+ UserType,
185
+ AttachmentType,
186
+ EventType,
187
+ MessageType,
188
+ ReactionType
189
+ > | null;
190
+ wsFallback?: WSConnectionFallback<
191
+ AttachmentType,
192
+ ChannelType,
193
+ CommandType,
194
+ EventType,
195
+ MessageType,
196
+ ReactionType,
197
+ UserType
198
+ >;
199
199
  wsPromise: ConnectAPIResponse<ChannelType, CommandType, UserType> | null;
200
200
  consecutiveFailures: number;
201
201
  insightMetrics: InsightMetrics;
202
+ defaultWSTimeoutWithFallback: number;
203
+ defaultWSTimeout: number;
202
204
 
203
205
  /**
204
206
  * Initialize a client
@@ -221,11 +223,7 @@ export class StreamChat<
221
223
  */
222
224
  constructor(key: string, options?: StreamChatOptions);
223
225
  constructor(key: string, secret?: string, options?: StreamChatOptions);
224
- constructor(
225
- key: string,
226
- secretOrOptions?: StreamChatOptions | string,
227
- options?: StreamChatOptions,
228
- ) {
226
+ constructor(key: string, secretOrOptions?: StreamChatOptions | string, options?: StreamChatOptions) {
229
227
  // set the key
230
228
  this.key = key;
231
229
  this.listeners = {};
@@ -240,16 +238,9 @@ export class StreamChat<
240
238
  }
241
239
 
242
240
  // set the options... and figure out defaults...
243
- const inputOptions = options
244
- ? options
245
- : secretOrOptions && !isString(secretOrOptions)
246
- ? secretOrOptions
247
- : {};
248
-
249
- this.browser =
250
- typeof inputOptions.browser !== 'undefined'
251
- ? inputOptions.browser
252
- : typeof window !== 'undefined';
241
+ const inputOptions = options ? options : secretOrOptions && !isString(secretOrOptions) ? secretOrOptions : {};
242
+
243
+ this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';
253
244
  this.node = !this.browser;
254
245
 
255
246
  this.options = {
@@ -295,6 +286,9 @@ export class StreamChat<
295
286
  this.consecutiveFailures = 0;
296
287
  this.insightMetrics = new InsightMetrics();
297
288
 
289
+ this.defaultWSTimeoutWithFallback = 6000;
290
+ this.defaultWSTimeout = 15000;
291
+
298
292
  /**
299
293
  * logger function should accept 3 parameters:
300
294
  * @param logLevel string
@@ -370,67 +364,43 @@ export class StreamChat<
370
364
  * StreamChat.getInstance('api_key', "secret", { httpsAgent: customAgent })
371
365
  */
372
366
  public static getInstance<
373
- AttachmentType extends UnknownType = UnknownType,
374
- ChannelType extends UnknownType = UnknownType,
367
+ AttachmentType extends UR = UR,
368
+ ChannelType extends UR = UR,
375
369
  CommandType extends string = LiteralStringForUnion,
376
- EventType extends UnknownType = UnknownType,
377
- MessageType extends UnknownType = UnknownType,
378
- ReactionType extends UnknownType = UnknownType,
379
- UserType extends UnknownType = UnknownType
370
+ EventType extends UR = UR,
371
+ MessageType extends UR = UR,
372
+ ReactionType extends UR = UR,
373
+ UserType extends UR = UR
380
374
  >(
381
375
  key: string,
382
376
  options?: StreamChatOptions,
383
- ): StreamChat<
384
- AttachmentType,
385
- ChannelType,
386
- CommandType,
387
- EventType,
388
- MessageType,
389
- ReactionType,
390
- UserType
391
- >;
377
+ ): StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
392
378
  public static getInstance<
393
- AttachmentType extends UnknownType = UnknownType,
394
- ChannelType extends UnknownType = UnknownType,
379
+ AttachmentType extends UR = UR,
380
+ ChannelType extends UR = UR,
395
381
  CommandType extends string = LiteralStringForUnion,
396
- EventType extends UnknownType = UnknownType,
397
- MessageType extends UnknownType = UnknownType,
398
- ReactionType extends UnknownType = UnknownType,
399
- UserType extends UnknownType = UnknownType
382
+ EventType extends UR = UR,
383
+ MessageType extends UR = UR,
384
+ ReactionType extends UR = UR,
385
+ UserType extends UR = UR
400
386
  >(
401
387
  key: string,
402
388
  secret?: string,
403
389
  options?: StreamChatOptions,
404
- ): StreamChat<
405
- AttachmentType,
406
- ChannelType,
407
- CommandType,
408
- EventType,
409
- MessageType,
410
- ReactionType,
411
- UserType
412
- >;
390
+ ): StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
413
391
  public static getInstance<
414
- AttachmentType extends UnknownType = UnknownType,
415
- ChannelType extends UnknownType = UnknownType,
392
+ AttachmentType extends UR = UR,
393
+ ChannelType extends UR = UR,
416
394
  CommandType extends string = LiteralStringForUnion,
417
- EventType extends UnknownType = UnknownType,
418
- MessageType extends UnknownType = UnknownType,
419
- ReactionType extends UnknownType = UnknownType,
420
- UserType extends UnknownType = UnknownType
395
+ EventType extends UR = UR,
396
+ MessageType extends UR = UR,
397
+ ReactionType extends UR = UR,
398
+ UserType extends UR = UR
421
399
  >(
422
400
  key: string,
423
401
  secretOrOptions?: StreamChatOptions | string,
424
402
  options?: StreamChatOptions,
425
- ): StreamChat<
426
- AttachmentType,
427
- ChannelType,
428
- CommandType,
429
- EventType,
430
- MessageType,
431
- ReactionType,
432
- UserType
433
- > {
403
+ ): StreamChat<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType> {
434
404
  if (!StreamChat._instance) {
435
405
  if (typeof secretOrOptions === 'string') {
436
406
  StreamChat._instance = new StreamChat<
@@ -479,7 +449,9 @@ export class StreamChat<
479
449
  this.wsBaseURL = this.baseURL.replace('http', 'ws').replace(':3030', ':8800');
480
450
  }
481
451
 
482
- _hasConnectionID = () => Boolean(this.wsConnection?.connectionID);
452
+ _getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;
453
+
454
+ _hasConnectionID = () => Boolean(this._getConnectionID());
483
455
 
484
456
  /**
485
457
  * connectUser - Set the current user and open a WebSocket connection
@@ -514,10 +486,7 @@ export class StreamChat<
514
486
  );
515
487
  }
516
488
 
517
- if (
518
- (this._isUsingServerAuth() || this.node) &&
519
- !this.options.allowServerSideConnect
520
- ) {
489
+ if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {
521
490
  console.warn(
522
491
  '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.',
523
492
  );
@@ -560,9 +529,7 @@ export class StreamChat<
560
529
  _setToken = (user: UserResponse<UserType>, userTokenOrProvider: TokenOrProvider) =>
561
530
  this.tokenManager.setTokenOrProvider(userTokenOrProvider, user);
562
531
 
563
- _setUser(
564
- user: OwnUserResponse<ChannelType, CommandType, UserType> | UserResponse<UserType>,
565
- ) {
532
+ _setUser(user: OwnUserResponse<ChannelType, CommandType, UserType> | UserResponse<UserType>) {
566
533
  /**
567
534
  * This one is used by the frontend. This is a copy of the current user object stored on backend.
568
535
  * It contains reserved properties and own user properties which are not present in `this._user`.
@@ -585,17 +552,14 @@ export class StreamChat<
585
552
  * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming succesful disconnection.
586
553
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
587
554
  */
588
- closeConnection = (timeout?: number) => {
555
+ closeConnection = async (timeout?: number) => {
589
556
  if (this.cleaningIntervalRef != null) {
590
557
  clearInterval(this.cleaningIntervalRef);
591
558
  this.cleaningIntervalRef = undefined;
592
559
  }
593
560
 
594
- if (!this.wsConnection) {
595
- return Promise.resolve();
596
- }
597
-
598
- return this.wsConnection.disconnect(timeout);
561
+ await Promise.all([this.wsConnection?.disconnect(timeout), this.wsFallback?.disconnect(timeout)]);
562
+ return Promise.resolve();
599
563
  };
600
564
 
601
565
  /**
@@ -603,19 +567,13 @@ export class StreamChat<
603
567
  */
604
568
  openConnection = async () => {
605
569
  if (!this.userID) {
606
- throw Error(
607
- 'User is not set on client, use client.connectUser or client.connectAnonymousUser instead',
608
- );
570
+ throw Error('User is not set on client, use client.connectUser or client.connectAnonymousUser instead');
609
571
  }
610
572
 
611
- if (this.wsConnection?.isHealthy && this._hasConnectionID()) {
612
- this.logger(
613
- 'info',
614
- 'client:openConnection() - openConnection called twice, healthy connection already exists',
615
- {
616
- tags: ['connection', 'client'],
617
- },
618
- );
573
+ if ((this.wsConnection?.isHealthy || this.wsFallback?.isHealthy()) && this._hasConnectionID()) {
574
+ this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists', {
575
+ tags: ['connection', 'client'],
576
+ });
619
577
 
620
578
  return Promise.resolve();
621
579
  }
@@ -661,9 +619,7 @@ export class StreamChat<
661
619
  */
662
620
  async updateAppSettings(options: AppSettings) {
663
621
  if (options.apn_config?.p12_cert) {
664
- options.apn_config.p12_cert = Buffer.from(options.apn_config.p12_cert).toString(
665
- 'base64',
666
- );
622
+ options.apn_config.p12_cert = Buffer.from(options.apn_config.p12_cert).toString('base64');
667
623
  }
668
624
  return await this.patch<APIResponse>(this.baseURL + '/app', options);
669
625
  }
@@ -674,9 +630,7 @@ export class StreamChat<
674
630
  }
675
631
 
676
632
  if (before === '') {
677
- throw new Error(
678
- "Don't pass blank string for since, use null instead if resetting the token revoke",
679
- );
633
+ throw new Error("Don't pass blank string for since, use null instead if resetting the token revoke");
680
634
  }
681
635
 
682
636
  return before;
@@ -748,12 +702,8 @@ export class StreamChat<
748
702
  ...(data.messageID ? { message_id: data.messageID } : {}),
749
703
  ...(data.apnTemplate ? { apn_template: data.apnTemplate } : {}),
750
704
  ...(data.firebaseTemplate ? { firebase_template: data.firebaseTemplate } : {}),
751
- ...(data.firebaseDataTemplate
752
- ? { firebase_data_template: data.firebaseDataTemplate }
753
- : {}),
754
- ...(data.huaweiDataTemplate
755
- ? { huawei_data_template: data.huaweiDataTemplate }
756
- : {}),
705
+ ...(data.firebaseDataTemplate ? { firebase_data_template: data.firebaseDataTemplate } : {}),
706
+ ...(data.huaweiDataTemplate ? { huawei_data_template: data.huaweiDataTemplate } : {}),
757
707
  ...(data.skipDevices ? { skip_devices: true } : {}),
758
708
  });
759
709
  }
@@ -801,7 +751,7 @@ export class StreamChat<
801
751
  // reset client state
802
752
  this.state = new ClientState();
803
753
  // reset token manager
804
- this.tokenManager.reset();
754
+ setTimeout(this.tokenManager.reset); // delay reseting to use token for disconnect calls
805
755
 
806
756
  // close the WS connection
807
757
  return closePromise;
@@ -819,10 +769,7 @@ export class StreamChat<
819
769
  * connectAnonymousUser - Set an anonymous user and open a WebSocket connection
820
770
  */
821
771
  connectAnonymousUser = () => {
822
- if (
823
- (this._isUsingServerAuth() || this.node) &&
824
- !this.options.allowServerSideConnect
825
- ) {
772
+ if ((this._isUsingServerAuth() || this.node) && !this.options.allowServerSideConnect) {
826
773
  console.warn(
827
774
  '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.',
828
775
  );
@@ -857,9 +804,10 @@ export class StreamChat<
857
804
  let response: { access_token: string; user: UserResponse<UserType> } | undefined;
858
805
  this.anonymous = true;
859
806
  try {
860
- response = await this.post<
861
- APIResponse & { access_token: string; user: UserResponse<UserType> }
862
- >(this.baseURL + '/guest', { user });
807
+ response = await this.post<APIResponse & { access_token: string; user: UserResponse<UserType> }>(
808
+ this.baseURL + '/guest',
809
+ { user },
810
+ );
863
811
  } catch (e) {
864
812
  this.anonymous = false;
865
813
  throw e;
@@ -867,10 +815,7 @@ export class StreamChat<
867
815
  this.anonymous = false;
868
816
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
869
817
  const { created_at, updated_at, last_active, online, ...guestUser } = response.user;
870
- return await this.connectUser(
871
- guestUser as UserResponse<UserType>,
872
- response.access_token,
873
- );
818
+ return await this.connectUser(guestUser as UserResponse<UserType>, response.access_token);
874
819
  }
875
820
 
876
821
  /**
@@ -912,39 +857,15 @@ export class StreamChat<
912
857
  * @return {{ unsubscribe: () => void }} Description
913
858
  */
914
859
  on(
915
- callback: EventHandler<
916
- AttachmentType,
917
- ChannelType,
918
- CommandType,
919
- EventType,
920
- MessageType,
921
- ReactionType,
922
- UserType
923
- >,
860
+ callback: EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
924
861
  ): { unsubscribe: () => void };
925
862
  on(
926
863
  eventType: string,
927
- callback: EventHandler<
928
- AttachmentType,
929
- ChannelType,
930
- CommandType,
931
- EventType,
932
- MessageType,
933
- ReactionType,
934
- UserType
935
- >,
864
+ callback: EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
936
865
  ): { unsubscribe: () => void };
937
866
  on(
938
867
  callbackOrString:
939
- | EventHandler<
940
- AttachmentType,
941
- ChannelType,
942
- CommandType,
943
- EventType,
944
- MessageType,
945
- ReactionType,
946
- UserType
947
- >
868
+ | EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>
948
869
  | string,
949
870
  callbackOrNothing?: EventHandler<
950
871
  AttachmentType,
@@ -995,39 +916,15 @@ export class StreamChat<
995
916
  *
996
917
  */
997
918
  off(
998
- callback: EventHandler<
999
- AttachmentType,
1000
- ChannelType,
1001
- CommandType,
1002
- EventType,
1003
- MessageType,
1004
- ReactionType,
1005
- UserType
1006
- >,
919
+ callback: EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1007
920
  ): void;
1008
921
  off(
1009
922
  eventType: string,
1010
- callback: EventHandler<
1011
- AttachmentType,
1012
- ChannelType,
1013
- CommandType,
1014
- EventType,
1015
- MessageType,
1016
- ReactionType,
1017
- UserType
1018
- >,
923
+ callback: EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1019
924
  ): void;
1020
925
  off(
1021
926
  callbackOrString:
1022
- | EventHandler<
1023
- AttachmentType,
1024
- ChannelType,
1025
- CommandType,
1026
- EventType,
1027
- MessageType,
1028
- ReactionType,
1029
- UserType
1030
- >
927
+ | EventHandler<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>
1031
928
  | string,
1032
929
  callbackOrNothing?: EventHandler<
1033
930
  AttachmentType,
@@ -1082,15 +979,11 @@ export class StreamChat<
1082
979
  }
1083
980
 
1084
981
  _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {
1085
- this.logger(
1086
- 'info',
1087
- `client:${type} - Response - url: ${url} > status ${response.status}`,
1088
- {
1089
- tags: ['api', 'api_response', 'client'],
1090
- url,
1091
- response,
1092
- },
1093
- );
982
+ this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {
983
+ tags: ['api', 'api_response', 'client'],
984
+ url,
985
+ response,
986
+ });
1094
987
  }
1095
988
 
1096
989
  _logApiError(type: string, url: string, error: unknown) {
@@ -1139,15 +1032,14 @@ export class StreamChat<
1139
1032
  this._logApiResponse<T>(type, url, response);
1140
1033
  this.consecutiveFailures = 0;
1141
1034
  return this.handleResponse(response);
1142
- } catch (e) {
1035
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1036
+ } catch (e: any /**TODO: generalize error types */) {
1143
1037
  e.client_request_id = requestConfig.headers?.['x-client-request-id'];
1144
1038
  this._logApiError(type, url, e);
1145
1039
  this.consecutiveFailures += 1;
1146
1040
  if (e.response) {
1147
- if (
1148
- e.response.data.code === chatCodes.TOKEN_EXPIRED &&
1149
- !this.tokenManager.isStatic()
1150
- ) {
1041
+ /** connection_fallback depends on this token expiration logic */
1042
+ if (e.response.data.code === chatCodes.TOKEN_EXPIRED && !this.tokenManager.isStatic()) {
1151
1043
  if (this.consecutiveFailures > 1) {
1152
1044
  await sleep(retryInterval(this.consecutiveFailures));
1153
1045
  }
@@ -1205,9 +1097,7 @@ export class StreamChat<
1205
1097
  let err: Error & { code?: number; response?: AxiosResponse<T>; status?: number };
1206
1098
  err = new Error(`StreamChat error HTTP code: ${response.status}`);
1207
1099
  if (response.data && response.data.code) {
1208
- err = new Error(
1209
- `StreamChat error code ${response.data.code}: ${response.data.message}`,
1210
- );
1100
+ err = new Error(`StreamChat error code ${response.data.code}: ${response.data.message}`);
1211
1101
  err.code = response.data.code;
1212
1102
  }
1213
1103
  err.response = response;
@@ -1224,16 +1114,10 @@ export class StreamChat<
1224
1114
  }
1225
1115
 
1226
1116
  dispatchEvent = (
1227
- event: Event<
1228
- AttachmentType,
1229
- ChannelType,
1230
- CommandType,
1231
- EventType,
1232
- MessageType,
1233
- ReactionType,
1234
- UserType
1235
- >,
1117
+ event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1236
1118
  ) => {
1119
+ if (!event.received_at) event.received_at = new Date();
1120
+
1237
1121
  // client event handlers
1238
1122
  const postListenerCallbacks = this._handleClientEvent(event);
1239
1123
 
@@ -1265,7 +1149,6 @@ export class StreamChat<
1265
1149
  ReactionType,
1266
1150
  UserType
1267
1151
  >;
1268
- event.received_at = new Date();
1269
1152
  this.dispatchEvent(event);
1270
1153
  };
1271
1154
 
@@ -1350,15 +1233,7 @@ export class StreamChat<
1350
1233
  * @param {Event} event
1351
1234
  */
1352
1235
  _handleUserEvent = (
1353
- event: Event<
1354
- AttachmentType,
1355
- ChannelType,
1356
- CommandType,
1357
- EventType,
1358
- MessageType,
1359
- ReactionType,
1360
- UserType
1361
- >,
1236
+ event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1362
1237
  ) => {
1363
1238
  if (!event.user) {
1364
1239
  return;
@@ -1400,42 +1275,22 @@ export class StreamChat<
1400
1275
  this._updateUserMessageReferences(event.user);
1401
1276
  }
1402
1277
 
1403
- if (
1404
- event.type === 'user.deleted' &&
1405
- event.user.deleted_at &&
1406
- (event.mark_messages_deleted || event.hard_delete)
1407
- ) {
1278
+ if (event.type === 'user.deleted' && event.user.deleted_at && (event.mark_messages_deleted || event.hard_delete)) {
1408
1279
  this._deleteUserMessageReference(event.user, event.hard_delete);
1409
1280
  }
1410
1281
  };
1411
1282
 
1412
1283
  _handleClientEvent(
1413
- event: Event<
1414
- AttachmentType,
1415
- ChannelType,
1416
- CommandType,
1417
- EventType,
1418
- MessageType,
1419
- ReactionType,
1420
- UserType
1421
- >,
1284
+ event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1422
1285
  ) {
1423
1286
  const client = this;
1424
1287
  const postListenerCallbacks = [];
1425
- this.logger(
1426
- 'info',
1427
- `client:_handleClientEvent - Received event of type { ${event.type} }`,
1428
- {
1429
- tags: ['event', 'client'],
1430
- event,
1431
- },
1432
- );
1288
+ this.logger('info', `client:_handleClientEvent - Received event of type { ${event.type} }`, {
1289
+ tags: ['event', 'client'],
1290
+ event,
1291
+ });
1433
1292
 
1434
- if (
1435
- event.type === 'user.presence.changed' ||
1436
- event.type === 'user.updated' ||
1437
- event.type === 'user.deleted'
1438
- ) {
1293
+ if (event.type === 'user.presence.changed' || event.type === 'user.updated' || event.type === 'user.deleted') {
1439
1294
  this._handleUserEvent(event);
1440
1295
  }
1441
1296
 
@@ -1454,12 +1309,8 @@ export class StreamChat<
1454
1309
  const currentMutedChannelIds: string[] = [];
1455
1310
  const nextMutedChannelIds: string[] = [];
1456
1311
 
1457
- this.mutedChannels.forEach(
1458
- (mute) => mute.channel && currentMutedChannelIds.push(mute.channel.cid),
1459
- );
1460
- event.me.channel_mutes.forEach(
1461
- (mute) => mute.channel && nextMutedChannelIds.push(mute.channel.cid),
1462
- );
1312
+ this.mutedChannels.forEach((mute) => mute.channel && currentMutedChannelIds.push(mute.channel.cid));
1313
+ event.me.channel_mutes.forEach((mute) => mute.channel && nextMutedChannelIds.push(mute.channel.cid));
1463
1314
 
1464
1315
  /** Set the unread count of un-muted channels to 0, which is the behaviour of backend */
1465
1316
  currentMutedChannelIds.forEach((cid) => {
@@ -1475,11 +1326,7 @@ export class StreamChat<
1475
1326
  this.mutedUsers = event.me.mutes;
1476
1327
  }
1477
1328
 
1478
- if (
1479
- (event.type === 'channel.deleted' ||
1480
- event.type === 'notification.channel_deleted') &&
1481
- event.cid
1482
- ) {
1329
+ if ((event.type === 'channel.deleted' || event.type === 'notification.channel_deleted') && event.cid) {
1483
1330
  client.state.deleteAllChannelReference(event.cid);
1484
1331
  this.activeChannels[event.cid]?._disconnect();
1485
1332
 
@@ -1499,9 +1346,7 @@ export class StreamChat<
1499
1346
  const mute = this.mutedChannels[i];
1500
1347
  if (mute.channel?.cid === cid) {
1501
1348
  muteStatus = {
1502
- muted: mute.expires
1503
- ? new Date(mute.expires).getTime() > new Date().getTime()
1504
- : true,
1349
+ muted: mute.expires ? new Date(mute.expires).getTime() > new Date().getTime() : true,
1505
1350
  createdAt: mute.created_at ? new Date(mute.created_at) : new Date(),
1506
1351
  expiresAt: mute.expires ? new Date(mute.expires) : null,
1507
1352
  };
@@ -1521,30 +1366,12 @@ export class StreamChat<
1521
1366
  }
1522
1367
 
1523
1368
  _callClientListeners = (
1524
- event: Event<
1525
- AttachmentType,
1526
- ChannelType,
1527
- CommandType,
1528
- EventType,
1529
- MessageType,
1530
- ReactionType,
1531
- UserType
1532
- >,
1369
+ event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>,
1533
1370
  ) => {
1534
1371
  const client = this;
1535
1372
  // gather and call the listeners
1536
1373
  const listeners: Array<
1537
- (
1538
- event: Event<
1539
- AttachmentType,
1540
- ChannelType,
1541
- CommandType,
1542
- EventType,
1543
- MessageType,
1544
- ReactionType,
1545
- UserType
1546
- >,
1547
- ) => void
1374
+ (event: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>) => void
1548
1375
  > = [];
1549
1376
  if (client.listeners.all) {
1550
1377
  listeners.push(...client.listeners.all);
@@ -1560,21 +1387,15 @@ export class StreamChat<
1560
1387
  };
1561
1388
 
1562
1389
  recoverState = async () => {
1563
- this.logger(
1564
- 'info',
1565
- `client:recoverState() - Start of recoverState with connectionID ${this.wsConnection?.connectionID}`,
1566
- {
1567
- tags: ['connection'],
1568
- },
1569
- );
1390
+ this.logger('info', `client:recoverState() - Start of recoverState with connectionID ${this._getConnectionID()}`, {
1391
+ tags: ['connection'],
1392
+ });
1570
1393
 
1571
1394
  const cids = Object.keys(this.activeChannels);
1572
1395
  if (cids.length && this.recoverStateOnReconnect) {
1573
- this.logger(
1574
- 'info',
1575
- `client:recoverState() - Start the querying of ${cids.length} channels`,
1576
- { tags: ['connection', 'client'] },
1577
- );
1396
+ this.logger('info', `client:recoverState() - Start the querying of ${cids.length} channels`, {
1397
+ tags: ['connection', 'client'],
1398
+ });
1578
1399
 
1579
1400
  await this.queryChannels(
1580
1401
  { cid: { $in: cids } } as ChannelFilters<ChannelType, CommandType, UserType>,
@@ -1603,57 +1424,83 @@ export class StreamChat<
1603
1424
  * @private
1604
1425
  */
1605
1426
  async connect() {
1606
- const client = this;
1607
- this.failures = 0;
1608
-
1609
- if (client.userID == null || this._user == null) {
1610
- throw Error(
1611
- 'Call connectUser or connectAnonymousUser before starting the connection',
1612
- );
1427
+ if (!this.userID || !this._user) {
1428
+ throw Error('Call connectUser or connectAnonymousUser before starting the connection');
1613
1429
  }
1614
-
1615
- if (client.wsBaseURL == null) {
1430
+ if (!this.wsBaseURL) {
1616
1431
  throw Error('Websocket base url not set');
1617
1432
  }
1618
-
1619
- if (client.clientID == null) {
1433
+ if (!this.clientID) {
1620
1434
  throw Error('clientID is not set');
1621
1435
  }
1622
1436
 
1623
1437
  if (!this.wsConnection && (this.options.warmUp || this.options.enableInsights)) {
1624
- this.sayHi();
1438
+ this._sayHi();
1625
1439
  }
1626
1440
 
1627
1441
  // The StableWSConnection handles all the reconnection logic.
1628
- this.wsConnection = new StableWSConnection<ChannelType, CommandType, UserType>({
1629
- wsBaseURL: client.wsBaseURL,
1630
- clientID: client.clientID,
1631
- userID: client.userID,
1632
- tokenManager: client.tokenManager,
1633
- user: this._user,
1634
- authType: this.getAuthType(),
1635
- userAgent: this.getUserAgent(),
1636
- apiKey: this.key,
1637
- recoverCallback: this.recoverState,
1638
- messageCallback: this.handleEvent,
1639
- eventCallback: this.dispatchEvent as (event: ConnectionChangeEvent) => void,
1640
- logger: this.logger,
1641
- device: this.options.device,
1642
- postInsights: this.options.enableInsights ? this.postInsights : undefined,
1643
- insightMetrics: this.insightMetrics,
1644
- });
1645
- return await this.wsConnection.connect();
1442
+ this.wsConnection = new StableWSConnection<
1443
+ ChannelType,
1444
+ CommandType,
1445
+ UserType,
1446
+ AttachmentType,
1447
+ EventType,
1448
+ MessageType,
1449
+ ReactionType
1450
+ >({ client: this });
1451
+
1452
+ try {
1453
+ // if fallback is used before, continue using it instead of waiting for WS to fail
1454
+ if (this.wsFallback) {
1455
+ return await this.wsFallback.connect();
1456
+ }
1457
+
1458
+ // if WSFallback is enabled, ws connect should timeout faster so fallback can try
1459
+ return await this.wsConnection.connect(
1460
+ this.options.enableWSFallback ? this.defaultWSTimeoutWithFallback : this.defaultWSTimeout,
1461
+ );
1462
+ } catch (err) {
1463
+ // run fallback only if it's WS/Network error and not a normal API error
1464
+ // make sure browser is online before even trying the longpoll
1465
+ if (this.options.enableWSFallback && isWSFailure(err) && isOnline()) {
1466
+ this.logger('info', 'client:connect() - WS failed, fallback to longpoll', { tags: ['connection', 'client'] });
1467
+ // @ts-expect-error
1468
+ this.dispatchEvent({ type: 'transport.changed', mode: 'longpoll' });
1469
+
1470
+ this.wsConnection._destroyCurrentWSConnection();
1471
+ this.wsConnection.disconnect().then(); // close WS so no retry
1472
+ this.wsFallback = new WSConnectionFallback<
1473
+ AttachmentType,
1474
+ ChannelType,
1475
+ CommandType,
1476
+ EventType,
1477
+ MessageType,
1478
+ ReactionType,
1479
+ UserType
1480
+ >({ client: this });
1481
+ return await this.wsFallback.connect();
1482
+ }
1483
+
1484
+ throw err;
1485
+ }
1646
1486
  }
1647
1487
 
1648
- sayHi() {
1488
+ /**
1489
+ * Check the connectivity with server for warmup purpose.
1490
+ *
1491
+ * @private
1492
+ */
1493
+ _sayHi() {
1649
1494
  const client_request_id = randomId();
1650
1495
  const opts = { headers: { 'x-client-request-id': client_request_id } };
1651
1496
  this.doAxiosRequest('get', this.baseURL + '/hi', null, opts).catch((e) => {
1652
- this.postInsights('http_hi_failed', {
1653
- api_key: this.key,
1654
- err: e,
1655
- client_request_id,
1656
- });
1497
+ if (this.options.enableInsights) {
1498
+ postInsights('http_hi_failed', {
1499
+ api_key: this.key,
1500
+ err: e,
1501
+ client_request_id,
1502
+ });
1503
+ }
1657
1504
  });
1658
1505
  }
1659
1506
 
@@ -1667,11 +1514,7 @@ export class StreamChat<
1667
1514
  *
1668
1515
  * @return {Promise<APIResponse & { users: Array<UserResponse<UserType>> }>} User Query Response
1669
1516
  */
1670
- async queryUsers(
1671
- filterConditions: UserFilters<UserType>,
1672
- sort: UserSort<UserType> = [],
1673
- options: UserOptions = {},
1674
- ) {
1517
+ async queryUsers(filterConditions: UserFilters<UserType>, sort: UserSort<UserType> = [], options: UserOptions = {}) {
1675
1518
  const defaultOptions = {
1676
1519
  presence: false,
1677
1520
  };
@@ -1737,10 +1580,7 @@ export class StreamChat<
1737
1580
  *
1738
1581
  * @return {Promise<MessageFlagsResponse<ChannelType, CommandType, UserType>>} Message Flags Response
1739
1582
  */
1740
- async queryMessageFlags(
1741
- filterConditions: MessageFlagsFilters = {},
1742
- options: MessageFlagsPaginationOptions = {},
1743
- ) {
1583
+ async queryMessageFlags(filterConditions: MessageFlagsFilters = {}, options: MessageFlagsPaginationOptions = {}) {
1744
1584
  // Return a list of message flags
1745
1585
  return await this.get<MessageFlagsResponse<ChannelType, CommandType, UserType>>(
1746
1586
  this.baseURL + '/moderation/flags/message',
@@ -1794,14 +1634,7 @@ export class StreamChat<
1794
1634
  };
1795
1635
 
1796
1636
  const data = await this.post<{
1797
- channels: ChannelAPIResponse<
1798
- AttachmentType,
1799
- ChannelType,
1800
- CommandType,
1801
- MessageType,
1802
- ReactionType,
1803
- UserType
1804
- >[];
1637
+ channels: ChannelAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>[];
1805
1638
  }>(this.baseURL + '/channels', payload);
1806
1639
 
1807
1640
  const channels: Channel<
@@ -1847,34 +1680,16 @@ export class StreamChat<
1847
1680
  */
1848
1681
  async search(
1849
1682
  filterConditions: ChannelFilters<ChannelType, CommandType, UserType>,
1850
- query:
1851
- | string
1852
- | MessageFilters<
1853
- AttachmentType,
1854
- ChannelType,
1855
- CommandType,
1856
- MessageType,
1857
- ReactionType,
1858
- UserType
1859
- >,
1683
+ query: string | MessageFilters<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>,
1860
1684
  options: SearchOptions<MessageType> = {},
1861
1685
  ) {
1862
1686
  if (options.offset && (options.sort || options.next)) {
1863
1687
  throw Error(`Cannot specify offset with sort or next parameters`);
1864
1688
  }
1865
- const payload: SearchPayload<
1866
- AttachmentType,
1867
- ChannelType,
1868
- CommandType,
1869
- MessageType,
1870
- ReactionType,
1871
- UserType
1872
- > = {
1689
+ const payload: SearchPayload<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType> = {
1873
1690
  filter_conditions: filterConditions,
1874
1691
  ...options,
1875
- sort: options.sort
1876
- ? normalizeQuerySort<SearchMessageSortBase<MessageType>>(options.sort)
1877
- : undefined,
1692
+ sort: options.sort ? normalizeQuerySort<SearchMessageSortBase<MessageType>>(options.sort) : undefined,
1878
1693
  };
1879
1694
  if (typeof query === 'string') {
1880
1695
  payload.query = query;
@@ -1888,14 +1703,7 @@ export class StreamChat<
1888
1703
  await this.setUserPromise;
1889
1704
 
1890
1705
  return await this.get<
1891
- SearchAPIResponse<
1892
- AttachmentType,
1893
- ChannelType,
1894
- CommandType,
1895
- MessageType,
1896
- ReactionType,
1897
- UserType
1898
- >
1706
+ SearchAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>
1899
1707
  >(this.baseURL + '/search', {
1900
1708
  payload,
1901
1709
  });
@@ -1910,7 +1718,7 @@ export class StreamChat<
1910
1718
  *
1911
1719
  */
1912
1720
  setLocalDevice(device: BaseDeviceFields) {
1913
- if (this.wsConnection) {
1721
+ if (this.wsConnection || this.wsFallback) {
1914
1722
  throw new Error('you can only set device before opening a websocket connection');
1915
1723
  }
1916
1724
 
@@ -1986,14 +1794,7 @@ export class StreamChat<
1986
1794
  }
1987
1795
 
1988
1796
  _addChannelConfig(
1989
- channelState: ChannelAPIResponse<
1990
- AttachmentType,
1991
- ChannelType,
1992
- CommandType,
1993
- MessageType,
1994
- ReactionType,
1995
- UserType
1996
- >,
1797
+ channelState: ChannelAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>,
1997
1798
  ) {
1998
1799
  this.configs[channelState.channel.type] = channelState.channel.config;
1999
1800
  }
@@ -2016,27 +1817,11 @@ export class StreamChat<
2016
1817
  channelType: string,
2017
1818
  channelID?: string | null,
2018
1819
  custom?: ChannelData<ChannelType>,
2019
- ): Channel<
2020
- AttachmentType,
2021
- ChannelType,
2022
- CommandType,
2023
- EventType,
2024
- MessageType,
2025
- ReactionType,
2026
- UserType
2027
- >;
1820
+ ): Channel<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
2028
1821
  channel(
2029
1822
  channelType: string,
2030
1823
  custom?: ChannelData<ChannelType>,
2031
- ): Channel<
2032
- AttachmentType,
2033
- ChannelType,
2034
- CommandType,
2035
- EventType,
2036
- MessageType,
2037
- ReactionType,
2038
- UserType
2039
- >;
1824
+ ): Channel<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>;
2040
1825
  channel(
2041
1826
  channelType: string,
2042
1827
  channelIDOrCustom?: string | ChannelData<ChannelType> | null,
@@ -2054,15 +1839,12 @@ export class StreamChat<
2054
1839
  // support channel("messaging", undefined, {options})
2055
1840
  // support channel("messaging", "", {options})
2056
1841
  if (channelIDOrCustom == null || channelIDOrCustom === '') {
2057
- return new Channel<
2058
- AttachmentType,
2059
- ChannelType,
2060
- CommandType,
2061
- EventType,
2062
- MessageType,
2063
- ReactionType,
2064
- UserType
2065
- >(this, channelType, undefined, custom);
1842
+ return new Channel<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>(
1843
+ this,
1844
+ channelType,
1845
+ undefined,
1846
+ custom,
1847
+ );
2066
1848
  }
2067
1849
 
2068
1850
  // support channel("messaging", {options})
@@ -2115,9 +1897,7 @@ export class StreamChat<
2115
1897
  }
2116
1898
 
2117
1899
  if (key.indexOf(`${channelType}:!members-`) === 0) {
2118
- const membersStrInExistingChannel = Object.keys(channel.state.members)
2119
- .sort()
2120
- .join(',');
1900
+ const membersStrInExistingChannel = Object.keys(channel.state.members).sort().join(',');
2121
1901
  if (membersStrInExistingChannel === membersStr) {
2122
1902
  return channel;
2123
1903
  }
@@ -2156,11 +1936,7 @@ export class StreamChat<
2156
1936
  *
2157
1937
  * @return {channel} The channel object, initialize it using channel.watch()
2158
1938
  */
2159
- getChannelById = (
2160
- channelType: string,
2161
- channelID: string,
2162
- custom: ChannelData<ChannelType>,
2163
- ) => {
1939
+ getChannelById = (channelType: string, channelID: string, custom: ChannelData<ChannelType>) => {
2164
1940
  if (typeof channelID === 'string' && ~channelID.indexOf(':')) {
2165
1941
  throw Error(`Invalid channel id ${channelID}, can't contain the : character`);
2166
1942
  }
@@ -2308,10 +2084,7 @@ export class StreamChat<
2308
2084
  });
2309
2085
  }
2310
2086
 
2311
- async deactivateUser(
2312
- userID: string,
2313
- options?: { created_by_id?: string; mark_messages_deleted?: boolean },
2314
- ) {
2087
+ async deactivateUser(userID: string, options?: { created_by_id?: string; mark_messages_deleted?: boolean }) {
2315
2088
  return await this.post<APIResponse & { user: UserResponse<UserType> }>(
2316
2089
  this.baseURL + `/users/${userID}/deactivate`,
2317
2090
  {
@@ -2323,14 +2096,7 @@ export class StreamChat<
2323
2096
  async exportUser(userID: string, options?: Record<string, string>) {
2324
2097
  return await this.get<
2325
2098
  APIResponse & {
2326
- messages: MessageResponse<
2327
- AttachmentType,
2328
- ChannelType,
2329
- CommandType,
2330
- MessageType,
2331
- ReactionType,
2332
- UserType
2333
- >[];
2099
+ messages: MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>[];
2334
2100
  reactions: ReactionResponse<ReactionType, UserType>[];
2335
2101
  user: UserResponse<UserType>;
2336
2102
  }
@@ -2346,20 +2112,6 @@ export class StreamChat<
2346
2112
  * @returns {Promise<APIResponse>}
2347
2113
  */
2348
2114
  async banUser(targetUserID: string, options?: BanUserOptions<UserType>) {
2349
- if (options?.user_id !== undefined) {
2350
- options.banned_by_id = options.user_id;
2351
- delete options.user_id;
2352
- console.warn(
2353
- "banUser: 'user_id' is deprecated, please consider switching to 'banned_by_id'",
2354
- );
2355
- }
2356
- if (options?.user !== undefined) {
2357
- options.banned_by = options.user;
2358
- delete options.user;
2359
- console.warn(
2360
- "banUser: 'user' is deprecated, please consider switching to 'banned_by'",
2361
- );
2362
- }
2363
2115
  return await this.post<APIResponse>(this.baseURL + '/moderation/ban', {
2364
2116
  target_user_id: targetUserID,
2365
2117
  ...options,
@@ -2412,19 +2164,12 @@ export class StreamChat<
2412
2164
  * @param {MuteUserOptions<UserType>} [options]
2413
2165
  * @returns {Promise<MuteUserResponse<ChannelType, CommandType, UserType>>}
2414
2166
  */
2415
- async muteUser(
2416
- targetID: string,
2417
- userID?: string,
2418
- options: MuteUserOptions<UserType> = {},
2419
- ) {
2420
- return await this.post<MuteUserResponse<ChannelType, CommandType, UserType>>(
2421
- this.baseURL + '/moderation/mute',
2422
- {
2423
- target_id: targetID,
2424
- ...(userID ? { user_id: userID } : {}),
2425
- ...options,
2426
- },
2427
- );
2167
+ async muteUser(targetID: string, userID?: string, options: MuteUserOptions<UserType> = {}) {
2168
+ return await this.post<MuteUserResponse<ChannelType, CommandType, UserType>>(this.baseURL + '/moderation/mute', {
2169
+ target_id: targetID,
2170
+ ...(userID ? { user_id: userID } : {}),
2171
+ ...options,
2172
+ });
2428
2173
  }
2429
2174
 
2430
2175
  /** unmuteUser - unmutes a user
@@ -2463,13 +2208,10 @@ export class StreamChat<
2463
2208
  * @returns {Promise<APIResponse>}
2464
2209
  */
2465
2210
  async flagMessage(targetMessageID: string, options: { user_id?: string } = {}) {
2466
- return await this.post<FlagMessageResponse<UserType>>(
2467
- this.baseURL + '/moderation/flag',
2468
- {
2469
- target_message_id: targetMessageID,
2470
- ...options,
2471
- },
2472
- );
2211
+ return await this.post<FlagMessageResponse<UserType>>(this.baseURL + '/moderation/flag', {
2212
+ target_message_id: targetMessageID,
2213
+ ...options,
2214
+ });
2473
2215
  }
2474
2216
 
2475
2217
  /**
@@ -2479,13 +2221,10 @@ export class StreamChat<
2479
2221
  * @returns {Promise<APIResponse>}
2480
2222
  */
2481
2223
  async flagUser(targetID: string, options: { user_id?: string } = {}) {
2482
- return await this.post<FlagUserResponse<UserType>>(
2483
- this.baseURL + '/moderation/flag',
2484
- {
2485
- target_user_id: targetID,
2486
- ...options,
2487
- },
2488
- );
2224
+ return await this.post<FlagUserResponse<UserType>>(this.baseURL + '/moderation/flag', {
2225
+ target_user_id: targetID,
2226
+ ...options,
2227
+ });
2489
2228
  }
2490
2229
 
2491
2230
  /**
@@ -2495,13 +2234,10 @@ export class StreamChat<
2495
2234
  * @returns {Promise<APIResponse>}
2496
2235
  */
2497
2236
  async unflagMessage(targetMessageID: string, options: { user_id?: string } = {}) {
2498
- return await this.post<FlagMessageResponse<UserType>>(
2499
- this.baseURL + '/moderation/unflag',
2500
- {
2501
- target_message_id: targetMessageID,
2502
- ...options,
2503
- },
2504
- );
2237
+ return await this.post<FlagMessageResponse<UserType>>(this.baseURL + '/moderation/unflag', {
2238
+ target_message_id: targetMessageID,
2239
+ ...options,
2240
+ });
2505
2241
  }
2506
2242
 
2507
2243
  /**
@@ -2511,13 +2247,10 @@ export class StreamChat<
2511
2247
  * @returns {Promise<APIResponse>}
2512
2248
  */
2513
2249
  async unflagUser(targetID: string, options: { user_id?: string } = {}) {
2514
- return await this.post<FlagUserResponse<UserType>>(
2515
- this.baseURL + '/moderation/unflag',
2516
- {
2517
- target_user_id: targetID,
2518
- ...options,
2519
- },
2520
- );
2250
+ return await this.post<FlagUserResponse<UserType>>(this.baseURL + '/moderation/unflag', {
2251
+ target_user_id: targetID,
2252
+ ...options,
2253
+ });
2521
2254
  }
2522
2255
 
2523
2256
  /**
@@ -2545,10 +2278,7 @@ export class StreamChat<
2545
2278
  }
2546
2279
 
2547
2280
  createCommand(data: CreateCommandOptions<CommandType>) {
2548
- return this.post<CreateCommandResponse<CommandType>>(
2549
- this.baseURL + '/commands',
2550
- data,
2551
- );
2281
+ return this.post<CreateCommandResponse<CommandType>>(this.baseURL + '/commands', data);
2552
2282
  }
2553
2283
 
2554
2284
  getCommand(name: string) {
@@ -2556,16 +2286,11 @@ export class StreamChat<
2556
2286
  }
2557
2287
 
2558
2288
  updateCommand(name: string, data: UpdateCommandOptions<CommandType>) {
2559
- return this.put<UpdateCommandResponse<CommandType>>(
2560
- this.baseURL + `/commands/${name}`,
2561
- data,
2562
- );
2289
+ return this.put<UpdateCommandResponse<CommandType>>(this.baseURL + `/commands/${name}`, data);
2563
2290
  }
2564
2291
 
2565
2292
  deleteCommand(name: string) {
2566
- return this.delete<DeleteCommandResponse<CommandType>>(
2567
- this.baseURL + `/commands/${name}`,
2568
- );
2293
+ return this.delete<DeleteCommandResponse<CommandType>>(this.baseURL + `/commands/${name}`);
2569
2294
  }
2570
2295
 
2571
2296
  listCommands() {
@@ -2574,23 +2299,15 @@ export class StreamChat<
2574
2299
 
2575
2300
  createChannelType(data: CreateChannelOptions<CommandType>) {
2576
2301
  const channelData = Object.assign({}, { commands: ['all'] }, data);
2577
- return this.post<CreateChannelResponse<CommandType>>(
2578
- this.baseURL + '/channeltypes',
2579
- channelData,
2580
- );
2302
+ return this.post<CreateChannelResponse<CommandType>>(this.baseURL + '/channeltypes', channelData);
2581
2303
  }
2582
2304
 
2583
2305
  getChannelType(channelType: string) {
2584
- return this.get<GetChannelTypeResponse<CommandType>>(
2585
- this.baseURL + `/channeltypes/${channelType}`,
2586
- );
2306
+ return this.get<GetChannelTypeResponse<CommandType>>(this.baseURL + `/channeltypes/${channelType}`);
2587
2307
  }
2588
2308
 
2589
2309
  updateChannelType(channelType: string, data: UpdateChannelOptions<CommandType>) {
2590
- return this.put<UpdateChannelResponse<CommandType>>(
2591
- this.baseURL + `/channeltypes/${channelType}`,
2592
- data,
2593
- );
2310
+ return this.put<UpdateChannelResponse<CommandType>>(this.baseURL + `/channeltypes/${channelType}`, data);
2594
2311
  }
2595
2312
 
2596
2313
  deleteChannelType(channelType: string) {
@@ -2611,15 +2328,7 @@ export class StreamChat<
2611
2328
  */
2612
2329
  async translateMessage(messageId: string, language: string) {
2613
2330
  return await this.post<
2614
- APIResponse &
2615
- MessageResponse<
2616
- AttachmentType,
2617
- ChannelType,
2618
- CommandType,
2619
- MessageType,
2620
- ReactionType,
2621
- UserType
2622
- >
2331
+ APIResponse & MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>
2623
2332
  >(this.baseURL + `/messages/${messageId}/translate`, {
2624
2333
  language,
2625
2334
  });
@@ -2648,10 +2357,7 @@ export class StreamChat<
2648
2357
  * @param {string | { id: string }} messageOrMessageId message object or message id
2649
2358
  * @param {string} errorText error message to report in case of message id absence
2650
2359
  */
2651
- _validateAndGetMessageId(
2652
- messageOrMessageId: string | { id: string },
2653
- errorText: string,
2654
- ) {
2360
+ _validateAndGetMessageId(messageOrMessageId: string | { id: string }, errorText: string) {
2655
2361
  let messageId: string;
2656
2362
  if (typeof messageOrMessageId === 'string') {
2657
2363
  messageId = messageOrMessageId;
@@ -2696,10 +2402,7 @@ export class StreamChat<
2696
2402
  * @param {string | { id: string }} messageOrMessageId message object or message id
2697
2403
  * @param {string | { id: string }} [userId]
2698
2404
  */
2699
- unpinMessage(
2700
- messageOrMessageId: string | { id: string },
2701
- userId?: string | { id: string },
2702
- ) {
2405
+ unpinMessage(messageOrMessageId: string | { id: string }, userId?: string | { id: string }) {
2703
2406
  const messageId = this._validateAndGetMessageId(
2704
2407
  messageOrMessageId,
2705
2408
  'Please specify the message id when calling unpinMessage',
@@ -2725,14 +2428,7 @@ export class StreamChat<
2725
2428
  * @return {APIResponse & { message: MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType> }} Response that includes the message
2726
2429
  */
2727
2430
  async updateMessage(
2728
- message: UpdatedMessage<
2729
- AttachmentType,
2730
- ChannelType,
2731
- CommandType,
2732
- MessageType,
2733
- ReactionType,
2734
- UserType
2735
- >,
2431
+ message: UpdatedMessage<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>,
2736
2432
  userId?: string | { id: string },
2737
2433
  options?: { skip_enrich_url?: boolean },
2738
2434
  ) {
@@ -2743,24 +2439,13 @@ export class StreamChat<
2743
2439
  const clonedMessage: Message = Object.assign({}, message);
2744
2440
  delete clonedMessage.id;
2745
2441
 
2746
- const reservedMessageFields: Array<
2747
- | 'command'
2748
- | 'created_at'
2749
- | 'html'
2750
- | 'latest_reactions'
2751
- | 'own_reactions'
2752
- | 'reaction_counts'
2753
- | 'reply_count'
2754
- | 'type'
2755
- | 'updated_at'
2756
- | 'user'
2757
- | '__html'
2758
- > = [
2442
+ const reservedMessageFields: Array<ReservedMessageFields> = [
2759
2443
  'command',
2760
2444
  'created_at',
2761
2445
  'html',
2762
2446
  'latest_reactions',
2763
2447
  'own_reactions',
2448
+ 'quoted_message',
2764
2449
  'reaction_counts',
2765
2450
  'reply_count',
2766
2451
  'type',
@@ -2787,24 +2472,12 @@ export class StreamChat<
2787
2472
  * Server always expects mentioned_users to be array of string. We are adding extra check, just in case
2788
2473
  * SDK missed this conversion.
2789
2474
  */
2790
- if (
2791
- Array.isArray(clonedMessage.mentioned_users) &&
2792
- !isString(clonedMessage.mentioned_users[0])
2793
- ) {
2794
- clonedMessage.mentioned_users = clonedMessage.mentioned_users.map(
2795
- (mu) => ((mu as unknown) as UserResponse).id,
2796
- );
2475
+ if (Array.isArray(clonedMessage.mentioned_users) && !isString(clonedMessage.mentioned_users[0])) {
2476
+ clonedMessage.mentioned_users = clonedMessage.mentioned_users.map((mu) => ((mu as unknown) as UserResponse).id);
2797
2477
  }
2798
2478
 
2799
2479
  return await this.post<
2800
- UpdateMessageAPIResponse<
2801
- AttachmentType,
2802
- ChannelType,
2803
- CommandType,
2804
- MessageType,
2805
- ReactionType,
2806
- UserType
2807
- >
2480
+ UpdateMessageAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>
2808
2481
  >(this.baseURL + `/messages/${message.id}`, {
2809
2482
  message: clonedMessage,
2810
2483
  ...options,
@@ -2838,14 +2511,7 @@ export class StreamChat<
2838
2511
  user = { id: userId };
2839
2512
  }
2840
2513
  return await this.put<
2841
- UpdateMessageAPIResponse<
2842
- AttachmentType,
2843
- ChannelType,
2844
- CommandType,
2845
- MessageType,
2846
- ReactionType,
2847
- UserType
2848
- >
2514
+ UpdateMessageAPIResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>
2849
2515
  >(this.baseURL + `/messages/${id}`, {
2850
2516
  ...partialMessageObject,
2851
2517
  ...options,
@@ -2860,14 +2526,7 @@ export class StreamChat<
2860
2526
  }
2861
2527
  return await this.delete<
2862
2528
  APIResponse & {
2863
- message: MessageResponse<
2864
- AttachmentType,
2865
- ChannelType,
2866
- CommandType,
2867
- MessageType,
2868
- ReactionType,
2869
- UserType
2870
- >;
2529
+ message: MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>;
2871
2530
  }
2872
2531
  >(this.baseURL + `/messages/${messageID}`, params);
2873
2532
  }
@@ -2875,24 +2534,14 @@ export class StreamChat<
2875
2534
  async getMessage(messageID: string) {
2876
2535
  return await this.get<
2877
2536
  APIResponse & {
2878
- message: MessageResponse<
2879
- AttachmentType,
2880
- ChannelType,
2881
- CommandType,
2882
- MessageType,
2883
- ReactionType,
2884
- UserType
2885
- >;
2537
+ message: MessageResponse<AttachmentType, ChannelType, CommandType, MessageType, ReactionType, UserType>;
2886
2538
  }
2887
2539
  >(this.baseURL + `/messages/${messageID}`);
2888
2540
  }
2889
2541
 
2890
2542
  getUserAgent() {
2891
2543
  return (
2892
- this.userAgent ||
2893
- `stream-chat-javascript-client-${this.node ? 'node' : 'browser'}-${
2894
- process.env.PKG_VERSION
2895
- }`
2544
+ this.userAgent || `stream-chat-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`
2896
2545
  );
2897
2546
  }
2898
2547
 
@@ -2911,11 +2560,13 @@ export class StreamChat<
2911
2560
  headers: {},
2912
2561
  config: {},
2913
2562
  },
2914
- ) {
2563
+ ): AxiosRequestConfig {
2915
2564
  const token = this._getToken();
2565
+ const authorization = token ? { Authorization: token } : undefined;
2916
2566
 
2917
2567
  if (!options.headers?.['x-client-request-id']) {
2918
2568
  options.headers = {
2569
+ ...options.headers,
2919
2570
  'x-client-request-id': randomId(),
2920
2571
  };
2921
2572
  }
@@ -2923,12 +2574,12 @@ export class StreamChat<
2923
2574
  return {
2924
2575
  params: {
2925
2576
  user_id: this.userID,
2926
- ...options.params,
2577
+ connection_id: this._getConnectionID(),
2927
2578
  api_key: this.key,
2928
- connection_id: this.wsConnection?.connectionID,
2579
+ ...options.params,
2929
2580
  },
2930
2581
  headers: {
2931
- Authorization: token,
2582
+ ...authorization,
2932
2583
  'stream-auth-type': this.getAuthType(),
2933
2584
  'X-Stream-Client': this.getUserAgent(),
2934
2585
  ...options.headers,
@@ -2956,6 +2607,20 @@ export class StreamChat<
2956
2607
  }, 500);
2957
2608
  }
2958
2609
 
2610
+ /**
2611
+ * encode ws url payload
2612
+ * @private
2613
+ * @returns json string
2614
+ */
2615
+ _buildWSPayload = (client_request_id?: string) => {
2616
+ return JSON.stringify({
2617
+ user_id: this.userID,
2618
+ user_details: this._user,
2619
+ device: this.options.device,
2620
+ client_request_id,
2621
+ });
2622
+ };
2623
+
2959
2624
  verifyWebhook(requestBody: string, xSignature: string) {
2960
2625
  return !!this.secret && CheckSignature(requestBody, this.secret, xSignature);
2961
2626
  }
@@ -3042,15 +2707,7 @@ export class StreamChat<
3042
2707
  sync(channel_cids: string[], last_sync_at: string) {
3043
2708
  return this.post<
3044
2709
  APIResponse & {
3045
- events: Event<
3046
- AttachmentType,
3047
- ChannelType,
3048
- CommandType,
3049
- EventType,
3050
- MessageType,
3051
- ReactionType,
3052
- UserType
3053
- >[];
2710
+ events: Event<AttachmentType, ChannelType, CommandType, EventType, MessageType, ReactionType, UserType>[];
3054
2711
  }
3055
2712
  >(`${this.baseURL}/sync`, {
3056
2713
  channel_cids,
@@ -3077,15 +2734,11 @@ export class StreamChat<
3077
2734
  }
3078
2735
 
3079
2736
  listBlockLists() {
3080
- return this.get<APIResponse & { blocklists: BlockListResponse[] }>(
3081
- `${this.baseURL}/blocklists`,
3082
- );
2737
+ return this.get<APIResponse & { blocklists: BlockListResponse[] }>(`${this.baseURL}/blocklists`);
3083
2738
  }
3084
2739
 
3085
2740
  getBlockList(name: string) {
3086
- return this.get<APIResponse & { blocklist: BlockListResponse }>(
3087
- `${this.baseURL}/blocklists/${name}`,
3088
- );
2741
+ return this.get<APIResponse & { blocklist: BlockListResponse }>(`${this.baseURL}/blocklists/${name}`);
3089
2742
  }
3090
2743
 
3091
2744
  updateBlockList(name: string, data: { words: string[] }) {
@@ -3096,18 +2749,12 @@ export class StreamChat<
3096
2749
  return this.delete<APIResponse>(`${this.baseURL}/blocklists/${name}`);
3097
2750
  }
3098
2751
 
3099
- exportChannels(
3100
- request: Array<ExportChannelRequest>,
3101
- options: ExportChannelOptions = {},
3102
- ) {
2752
+ exportChannels(request: Array<ExportChannelRequest>, options: ExportChannelOptions = {}) {
3103
2753
  const payload = {
3104
2754
  channels: request,
3105
2755
  ...options,
3106
2756
  };
3107
- return this.post<APIResponse & ExportChannelResponse>(
3108
- `${this.baseURL}/export_channels`,
3109
- payload,
3110
- );
2757
+ return this.post<APIResponse & ExportChannelResponse>(`${this.baseURL}/export_channels`, payload);
3111
2758
  }
3112
2759
 
3113
2760
  exportChannel(request: ExportChannelRequest, options?: ExportChannelOptions) {
@@ -3115,9 +2762,7 @@ export class StreamChat<
3115
2762
  }
3116
2763
 
3117
2764
  getExportChannelStatus(id: string) {
3118
- return this.get<APIResponse & ExportChannelStatusResponse>(
3119
- `${this.baseURL}/export_channels/${id}`,
3120
- );
2765
+ return this.get<APIResponse & ExportChannelStatusResponse>(`${this.baseURL}/export_channels/${id}`);
3121
2766
  }
3122
2767
 
3123
2768
  /**
@@ -3128,10 +2773,7 @@ export class StreamChat<
3128
2773
  * @return {Segment} The Created Segment
3129
2774
  */
3130
2775
  async createSegment(params: SegmentData) {
3131
- const { segment } = await this.post<{ segment: Segment }>(
3132
- this.baseURL + `/segments`,
3133
- { segment: params },
3134
- );
2776
+ const { segment } = await this.post<{ segment: Segment }>(this.baseURL + `/segments`, { segment: params });
3135
2777
  return segment;
3136
2778
  }
3137
2779
 
@@ -3143,9 +2785,7 @@ export class StreamChat<
3143
2785
  * @return {Segment} A Segment
3144
2786
  */
3145
2787
  async getSegment(id: string) {
3146
- const { segment } = await this.get<{ segment: Segment }>(
3147
- this.baseURL + `/segments/${id}`,
3148
- );
2788
+ const { segment } = await this.get<{ segment: Segment }>(this.baseURL + `/segments/${id}`);
3149
2789
  return segment;
3150
2790
  }
3151
2791
 
@@ -3156,10 +2796,7 @@ export class StreamChat<
3156
2796
  * @return {Segment[]} Segments
3157
2797
  */
3158
2798
  async listSegments(options: { limit?: number; offset?: number }) {
3159
- const { segments } = await this.get<{ segments: Segment[] }>(
3160
- this.baseURL + `/segments`,
3161
- options,
3162
- );
2799
+ const { segments } = await this.get<{ segments: Segment[] }>(this.baseURL + `/segments`, options);
3163
2800
  return segments;
3164
2801
  }
3165
2802
 
@@ -3172,10 +2809,7 @@ export class StreamChat<
3172
2809
  * @return {Segment} Updated Segment
3173
2810
  */
3174
2811
  async updateSegment(id: string, params: Partial<SegmentData>) {
3175
- const { segment } = await this.put<{ segment: Segment }>(
3176
- this.baseURL + `/segments/${id}`,
3177
- { segment: params },
3178
- );
2812
+ const { segment } = await this.put<{ segment: Segment }>(this.baseURL + `/segments/${id}`, { segment: params });
3179
2813
  return segment;
3180
2814
  }
3181
2815
 
@@ -3198,10 +2832,7 @@ export class StreamChat<
3198
2832
  * @return {Campaign} The Created Campaign
3199
2833
  */
3200
2834
  async createCampaign(params: CampaignData) {
3201
- const { campaign } = await this.post<{ campaign: Campaign }>(
3202
- this.baseURL + `/campaigns`,
3203
- { campaign: params },
3204
- );
2835
+ const { campaign } = await this.post<{ campaign: Campaign }>(this.baseURL + `/campaigns`, { campaign: params });
3205
2836
  return campaign;
3206
2837
  }
3207
2838
 
@@ -3213,9 +2844,7 @@ export class StreamChat<
3213
2844
  * @return {Campaign} A Campaign
3214
2845
  */
3215
2846
  async getCampaign(id: string) {
3216
- const { campaign } = await this.get<{ campaign: Campaign }>(
3217
- this.baseURL + `/campaigns/${id}`,
3218
- );
2847
+ const { campaign } = await this.get<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}`);
3219
2848
  return campaign;
3220
2849
  }
3221
2850
 
@@ -3226,10 +2855,7 @@ export class StreamChat<
3226
2855
  * @return {Campaign[]} Campaigns
3227
2856
  */
3228
2857
  async listCampaigns(options: { limit?: number; offset?: number }) {
3229
- const { campaigns } = await this.get<{ campaigns: Campaign[] }>(
3230
- this.baseURL + `/campaigns`,
3231
- options,
3232
- );
2858
+ const { campaigns } = await this.get<{ campaigns: Campaign[] }>(this.baseURL + `/campaigns`, options);
3233
2859
  return campaigns;
3234
2860
  }
3235
2861
 
@@ -3242,10 +2868,9 @@ export class StreamChat<
3242
2868
  * @return {Campaign} Updated Campaign
3243
2869
  */
3244
2870
  async updateCampaign(id: string, params: Partial<CampaignData>) {
3245
- const { campaign } = await this.put<{ campaign: Campaign }>(
3246
- this.baseURL + `/campaigns/${id}`,
3247
- { campaign: params },
3248
- );
2871
+ const { campaign } = await this.put<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}`, {
2872
+ campaign: params,
2873
+ });
3249
2874
  return campaign;
3250
2875
  }
3251
2876
 
@@ -3270,10 +2895,9 @@ export class StreamChat<
3270
2895
  */
3271
2896
  async scheduleCampaign(id: string, params: { sendAt: number }) {
3272
2897
  const { sendAt } = params;
3273
- const { campaign } = await this.patch<{ campaign: Campaign }>(
3274
- this.baseURL + `/campaigns/${id}/schedule`,
3275
- { send_at: sendAt },
3276
- );
2898
+ const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/schedule`, {
2899
+ send_at: sendAt,
2900
+ });
3277
2901
  return campaign;
3278
2902
  }
3279
2903
 
@@ -3285,9 +2909,7 @@ export class StreamChat<
3285
2909
  * @return {Campaign} Stopped Campaign
3286
2910
  */
3287
2911
  async stopCampaign(id: string) {
3288
- const { campaign } = await this.patch<{ campaign: Campaign }>(
3289
- this.baseURL + `/campaigns/${id}/stop`,
3290
- );
2912
+ const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/stop`);
3291
2913
  return campaign;
3292
2914
  }
3293
2915
 
@@ -3299,9 +2921,7 @@ export class StreamChat<
3299
2921
  * @return {Campaign} Resumed Campaign
3300
2922
  */
3301
2923
  async resumeCampaign(id: string) {
3302
- const { campaign } = await this.patch<{ campaign: Campaign }>(
3303
- this.baseURL + `/campaigns/${id}/resume`,
3304
- );
2924
+ const { campaign } = await this.patch<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/resume`);
3305
2925
  return campaign;
3306
2926
  }
3307
2927
 
@@ -3314,10 +2934,7 @@ export class StreamChat<
3314
2934
  */
3315
2935
  async testCampaign(id: string, params: { users: string[] }) {
3316
2936
  const { users } = params;
3317
- const { campaign } = await this.post<{ campaign: Campaign }>(
3318
- this.baseURL + `/campaigns/${id}/test`,
3319
- { users },
3320
- );
2937
+ const { campaign } = await this.post<{ campaign: Campaign }>(this.baseURL + `/campaigns/${id}/test`, { users });
3321
2938
  return campaign;
3322
2939
  }
3323
2940
 
@@ -3351,33 +2968,12 @@ export class StreamChat<
3351
2968
  * @return {DeleteChannelsResponse} Result of the soft deletion, if server-side, it holds the task ID as well
3352
2969
  */
3353
2970
  async deleteChannels(cids: string[], options: { hard_delete?: boolean } = {}) {
3354
- return await this.post<APIResponse & DeleteChannelsResponse>(
3355
- this.baseURL + `/channels/delete`,
3356
- { cids, ...options },
3357
- );
2971
+ return await this.post<APIResponse & DeleteChannelsResponse>(this.baseURL + `/channels/delete`, {
2972
+ cids,
2973
+ ...options,
2974
+ });
3358
2975
  }
3359
2976
 
3360
- postInsights = async (insightType: InsightTypes, insights: Record<string, unknown>) => {
3361
- const maxAttempts = 3;
3362
- for (let i = 0; i < maxAttempts; i++) {
3363
- try {
3364
- await this.axiosInstance.post(
3365
- `https://chat-insights.getstream.io/insights/${insightType}`,
3366
- insights,
3367
- );
3368
- } catch (e) {
3369
- this.logger('warn', `failed to send insights event ${insightType}`, {
3370
- tags: ['insights', 'connection'],
3371
- error: e,
3372
- insights,
3373
- });
3374
- await sleep((i + 1) * 3000);
3375
- continue;
3376
- }
3377
- break;
3378
- }
3379
- };
3380
-
3381
2977
  /**
3382
2978
  * deleteUsers - Batch Delete Users
3383
2979
  *
@@ -3390,21 +2986,11 @@ export class StreamChat<
3390
2986
  if (options?.user !== 'soft' && options?.user !== 'hard') {
3391
2987
  throw new Error('Invalid delete user options. user must be one of [soft hard]');
3392
2988
  }
3393
- if (
3394
- options.messages !== undefined &&
3395
- options.messages !== 'soft' &&
3396
- options.messages !== 'hard'
3397
- ) {
2989
+ if (options.messages !== undefined && options.messages !== 'soft' && options.messages !== 'hard') {
3398
2990
  throw new Error('Invalid delete user options. messages must be one of [soft hard]');
3399
2991
  }
3400
- if (
3401
- options.conversations !== undefined &&
3402
- options.conversations !== 'soft' &&
3403
- options.conversations !== 'hard'
3404
- ) {
3405
- throw new Error(
3406
- 'Invalid delete user options. conversations must be one of [soft hard]',
3407
- );
2992
+ if (options.conversations !== undefined && options.conversations !== 'soft' && options.conversations !== 'hard') {
2993
+ throw new Error('Invalid delete user options. conversations must be one of [soft hard]');
3408
2994
  }
3409
2995
  return await this.post<APIResponse & TaskResponse>(this.baseURL + `/users/delete`, {
3410
2996
  user_ids,