diff --git a/README.md b/README.md
index c558a67b3..c21cddf2e 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@
You can sign up for a Stream account at our [Get Started](https://getstream.io/chat/get_started/) page.
-This library can be used by both frontend and backend applications. For frontend, we have frameworks that are based on this library such as the [Flutter](https://github.com/GetStream/stream-chat-flutter), [React](https://github.com/GetStream/stream-chat-react) and [Angular](https://github.com/GetStream/stream-chat-angular) SDKs. For more information, check out our [docs](https://getstream.io/chat/docs/).
+This library can be used by both frontend and backend applications. For frontend, we have frameworks that are based on this library such as the [Flutter](https://github.com/GetStream/stream-chat-flutter), [React](https://github.com/GetStream/stream-chat-react) and [Angular](https://github.com/GetStream/stream-chat-angular) SDKs. For more information, check out our [documentation](https://getstream.io/chat/docs/).
## ⚙️ Installation
@@ -36,95 +36,95 @@ npm install stream-chat
yarn add stream-chat
```
-### JS deliver
+### jsDelivr
```html
```
-## ✨ Getting started
+## ✨ Getting Started
-The StreamChat client is setup to allow extension of the base types through use of generics when instantiated. The default instantiation has all generics set to `Record`.
-
-```typescript
+```ts
import { StreamChat } from 'stream-chat';
-// Or if you are on commonjs
-const StreamChat = require('stream-chat').StreamChat;
+// or if you are using CommonJS
+const { StreamChat } = require('stream-chat');
-const client = StreamChat.getInstance('YOUR_API_KEY', 'API_KEY_SECRET');
+const client = new StreamChat('API_KEY', 'API_SECRET', {
+ disableCache: true, // recommended option for server-side use
+ // ...other options like `baseURL`...
+});
-const channel = client.channel('messaging', 'TestChannel');
+// create a user
+await client.upsertUser({
+ id: 'vishal-1',
+ name: 'Vishal',
+});
+
+// create a channel
+const channel = client.channel('messaging', 'test-channel', { created_by_id: 'vishal-1' });
await channel.create();
+
+// send message
+const { message } = await channel.sendMessage({ text: 'This is a test message' });
+
+// send reaction
+await channel.sendReaction(message.id, { type: 'love', user: { id: 'vishal-1' } });
```
-Or you can customize the generics:
-
-```typescript
-type ChatChannel = { image: string; category?: string };
-type ChatUser1 = { nickname: string; age: number; admin?: boolean };
-type ChatUser2 = { nickname: string; avatar?: string };
-type UserMessage = { country?: string };
-type AdminMessage = { priorityLevel: number };
-type ChatAttachment = { originalURL?: string };
-type CustomReaction = { size?: number };
-type ChatEvent = { quitChannel?: boolean };
-type CustomCommands = 'giphy';
-
-type StreamType = {
- attachmentType: ChatAttachment;
- channelType: ChatChannel;
- commandType: CustomCommands;
- eventType: ChatEvent;
- messageType: UserMessage | AdminMessage;
- reactionType: CustomReaction;
- userType: ChatUser1 | ChatUser2;
-};
+The `StreamChat` client is set up to allow extension of the base types through use of module augmentation, custom types will carry through to all client returns and provide code-completion to queries (if supported). To extend Stream's entities with custom data you'll have to create a declaration file and make sure it's loaded by TypeScript, [see the list of extendable interfaces](https://github.com/GetStream/stream-chat-js/blob/master/src/custom_types.ts) and the example bellow using two of the most common ones:
-const client = StreamChat.getInstance('YOUR_API_KEY', 'API_KEY_SECRET');
+```ts
+// stream-custom-data.d.ts
-// Create channel
-const channel = client.channel('messaging', 'TestChannel');
-await channel.create();
+import 'stream-chat';
-// Create user
-await client.upsertUser({
- id: 'vishal-1',
- name: 'Vishal',
-});
+declare module 'stream-chat' {
+ interface CustomMessageData {
+ custom_property?: number;
+ }
+ interface CustomUserData {
+ profile_picture?: string;
+ }
+}
-// Send message
-const { message } = await channel.sendMessage({ text: `Test message` });
+// index.ts
-// Send reaction
-await channel.sendReaction(message.id, { type: 'love', user: { id: 'vishal-1' } });
+// property `profile_picture` is code-completed and expects type `string | undefined`
+await client.partialUpdateUser({ id: 'vishal-1', set: { profile_picture: 'https://random.picture/1.jpg' } });
+
+// property `custom_property` is code-completed and expects type `number | undefined`
+const { message } = await channel.sendMessage({ text: 'This is another test message', custom_property: 255 });
+
+message.custom_property; // in the response object as well
```
-Custom types provided when initializing the client will carry through to all client returns and provide intellisense to queries.
+> [!WARNING]
+> Generics mechanism has been removed in version `9.0.0` in favour of the module augmentation, please see [the release guide](https://getstream.io/chat/docs/node/upgrade-stream-chat-to-v9) on how to migrate.
-## 🔗 (Optional) Development Setup in Combination with our SDKs
+## 🔗 (Optional) Development Setup in Combination With Our SDKs
### Connect to [Stream Chat React Native SDK](https://github.com/GetStream/stream-chat-react-native)
-Run in the root of this repo
+Run in the root of this repository:
-```shell
+```sh
yarn link
```
-Run in the root of one of the example apps (SampleApp/TypeScriptMessaging) in the `stream-chat-react-native` repo
+Run in the root of one of the example applications (SampleApp/TypeScriptMessaging) in the `stream-chat-react-native` repository:
-```shell
+```sh
yarn link stream-chat
yarn start
```
-Open `metro.config.js` file and set value for watchFolders as
+Open `metro.config.js` file and set value for `watchFolders` as:
-```javascript
-const streamChatRoot = '{{CHANGE_TO_THE_PATH_TO_YOUR_PROJECT}}/stream-chat-js'
+```js
+const streamChatRoot = '/stream-chat-js'
module.exports = {
- // the rest of the metro config goes here
+ // the rest of the metro configuration goes here
...
watchFolders: [projectRoot].concat(alternateRoots).concat([streamChatRoot]),
resolver: {
@@ -139,17 +139,17 @@ module.exports = {
};
```
-Make sure to replace `{{CHANGE_TO_THE_PATH_TO_YOUR_PROJECT}}` with the correct path for the `stream-chat-js` folder as per your directory structure.
+Make sure to replace `` with the correct path for the `stream-chat-js` folder as per your directory structure.
-Run in the root of this repo
+Run in the root of this repository:
-```shell
+```sh
yarn start
```
-## 📚 More code examples
+## 📚 More Code Examples
-Head over to [docs/typescript.md](./docs/typescript.md) for more examples.
+Read up more on [Logging](./docs/logging.md) and [User Token](./docs/userToken.md) or visit our [documentation](https://getstream.io/chat/docs/) for more examples.
## ✍️ Contributing
@@ -157,7 +157,7 @@ We welcome code changes that improve this library or fix a problem, please make
Head over to [CONTRIBUTING.md](./CONTRIBUTING.md) for some development tips.
-## 🧑💻 We are hiring!
+## 🧑💻 We Are Hiring!
We've recently closed a [$38 million Series B funding round](https://techcrunch.com/2021/03/04/stream-raises-38m-as-its-chat-and-activity-feed-apis-power-communications-for-1b-users/) and we keep actively growing.
Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world.
diff --git a/assets/logo.svg b/assets/logo.svg
index 1c68c5ccc..ac2e18775 100644
--- a/assets/logo.svg
+++ b/assets/logo.svg
@@ -1,16 +1,31 @@
-
-
\ No newline at end of file
+
diff --git a/docs/typescript.md b/docs/typescript.md
deleted file mode 100644
index 118ba59b7..000000000
--- a/docs/typescript.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Typescript (v2.x.x)
-
-The StreamChat client is setup to allow extension of the base types through use of generics when instantiated. The default instantiation has all generics set to `Record`.
-
-```typescript
-StreamChat<{
- attachmentType: AttachmentType;
- channelType: ChannelType;
- commandType: CommandType;
- eventType: EventType;
- messageType: MessageType;
- reactionType: ReactionType;
- userType: UserType;
-}>
-```
-
-Custom types provided when initializing the client will carry through to all client returns and provide intellisense to queries.
-
-**NOTE:** If you utilize the `setAnonymousUser` function you must account for this in your user types.
-
-```typescript
-import { StreamChat } from 'stream-chat';
-// or if you are on commonjs
-const StreamChat = require('stream-chat').StreamChat;
-
-type ChatChannel = { image: string; category?: string };
-type ChatUser1 = { nickname: string; age: number; admin?: boolean };
-type ChatUser2 = { nickname: string; avatar?: string };
-type UserMessage = { country?: string };
-type AdminMessage = { priorityLevel: number };
-type ChatAttachment = { originalURL?: string };
-type CustomReaction = { size?: number };
-type ChatEvent = { quitChannel?: boolean };
-type CustomCommands = 'giphy';
-
-type StreamType = {
- attachmentType: ChatAttachment;
- channelType: ChatChannel;
- commandType: CustomCommands;
- eventType: ChatEvent;
- messageType: UserMessage | AdminMessage;
- reactionType: CustomReaction;
- userType: ChatUser1 | ChatUser2;
-};
-
-// Instantiate a new client (server side)
-// you can also use `new StreamChat()`
-const client = StreamChat.getInstance('YOUR_API_KEY', 'API_KEY_SECRET');
-
-/**
- * Instantiate a new client (client side)
- * Unused generics default to Record
- * with the exception of Command which defaults to string & {}
- */
-const client = StreamChat.getInstance('YOUR_API_KEY');
-```
-
-Query operations will return results that utilize the custom types added via generics. In addition the query filters are type checked and provide intellisense using both the key and type of the parameter to ensure accurate use.
-
-```typescript
-// Valid queries
-// users: { duration: string; users: UserResponse[]; }
-const users = await client.queryUsers({ id: '1080' });
-const users = await client.queryUsers({ nickname: 'streamUser' });
-const users = await client.queryUsers({ nickname: { $eq: 'streamUser' } });
-
-// Invalid queries
-const users = await client.queryUsers({ nickname: { $contains: ['stream'] } }); // $contains is only an operator on arrays
-const users = await client.queryUsers({ nickname: 1080 }); // nickname must be a string
-const users = await client.queryUsers({ name: { $eq: 1080 } }); // name must be a string
-```
-
-**Note:** If you have differing union types like `ChatUser1 | ChatUser2` or `UserMessage | AdminMessage` you can use [type guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types) to maintain type safety when dealing with the results of queries.
-
-```typescript
-function isChatUser1(user: ChatUser1 | ChatUser2): user is ChatUser1 {
- return (user as ChatUser1).age !== undefined;
-}
-
-function isAdminMessage(msg: UserMessage | AdminMessage): msg is AdminMessage {
- return (msg as AdminMessage).priorityLevel !== undefined;
-}
-```
-
-Intellisense, type checking, and return types are provided for all queries.
-
-```typescript
-const channel = client.channel('messaging', 'TestChannel');
-await channel.create();
-
-// Valid queries
-// messages: SearchAPIResponse
-const messages = await channel.search({ country: 'NL' });
-const messages = await channel.search({ priorityLevel: { $gt: 5 } });
-const messages = await channel.search({
- $and: [{ priorityLevel: { $gt: 5 } }, { deleted_at: { $exists: false } }],
-});
-
-// Invalid queries
-const messages = await channel.search({ country: { $eq: 5 } }); // country must be a string
-const messages = await channel.search({
- $or: [{ id: '2' }, { reaction_counts: { $eq: 'hello' } }],
-}); // reaction_counts must be a number
-```
-
-Custom types are carried into all creation functions as well.
-
-```typescript
-// Valid
-client.connectUser({ id: 'testId', nickname: 'testUser', age: 3 }, 'TestToken');
-client.connectUser({ id: 'testId', nickname: 'testUser', avatar: 'testAvatar' }, 'TestToken');
-
-// Invalid
-client.connectUser({ id: 'testId' }, 'TestToken'); // Type ChatUser1 | ChatUser2 requires nickname for both types
-client.connectUser({ id: 'testId', nickname: true }, 'TestToken'); // nickname must be a string
-client.connectUser({ id: 'testId', nickname: 'testUser', country: 'NL' }, 'TestToken'); // country does not exist on type ChatUser1 | ChatUser2
-```
-
-## More
-
-- [Logging](./logging.md)
-- [User Token](./userToken.md)
diff --git a/src/campaign.ts b/src/campaign.ts
index f4201cd12..ed0e23962 100644
--- a/src/campaign.ts
+++ b/src/campaign.ts
@@ -1,12 +1,12 @@
import { StreamChat } from './client';
-import { CampaignData, DefaultGenerics, ExtendableGenerics } from './types';
+import { CampaignData } from './types';
-export class Campaign {
+export class Campaign {
id: string | null;
data?: CampaignData;
- client: StreamChat;
+ client: StreamChat;
- constructor(client: StreamChat, id: string | null, data?: CampaignData) {
+ constructor(client: StreamChat, id: string | null, data?: CampaignData) {
this.client = client;
this.id = id;
this.data = data;
diff --git a/src/channel.ts b/src/channel.ts
index 94962b2eb..4f0d8e4de 100644
--- a/src/channel.ts
+++ b/src/channel.ts
@@ -1,7 +1,8 @@
import { ChannelState } from './channel_state';
import { generateChannelTempCid, logChatPromiseExecution, messageSetPagination, normalizeQuerySort } from './utils';
import { StreamChat } from './client';
-import {
+import { DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE } from './constants';
+import type {
APIResponse,
BanUserOptions,
ChannelAPIResponse,
@@ -14,18 +15,15 @@ import {
ChannelUpdateOptions,
CreateCallOptions,
CreateCallResponse,
- DefaultGenerics,
DeleteChannelAPIResponse,
Event,
EventAPIResponse,
EventHandler,
EventTypes,
- ExtendableGenerics,
FormatMessageResponse,
GetMultipleMessagesAPIResponse,
GetReactionsAPIResponse,
GetRepliesAPIResponse,
- InviteOptions,
MarkReadOptions,
MarkUnreadOptions,
MemberFilters,
@@ -62,23 +60,24 @@ import {
AIState,
MessageOptions,
PushPreference,
+ UpdateChannelOptions,
} from './types';
-import { Role } from './permissions';
-import { DEFAULT_QUERY_CHANNEL_MESSAGE_LIST_PAGE_SIZE } from './constants';
+import type { Role } from './permissions';
+import type { CustomChannelData } from './custom_types';
/**
* Channel - The Channel class manages it's own state.
*/
-export class Channel {
- _client: StreamChat;
+export class Channel {
+ _client: StreamChat;
type: string;
id: string | undefined;
- data: ChannelData | ChannelResponse | undefined;
- _data: ChannelData | ChannelResponse;
+ data: Partial | undefined;
+ _data: Partial;
cid: string;
/** */
- listeners: { [key: string]: (string | EventHandler)[] };
- state: ChannelState;
+ listeners: { [key: string]: (string | EventHandler)[] };
+ state: ChannelState;
/**
* This boolean is a vague indication of weather the channel exists on chat backend.
*
@@ -103,19 +102,14 @@ export class Channel} client the chat client
+ * @param {StreamChat} client the chat client
* @param {string} type the type of channel
* @param {string} [id] the id of the chat
- * @param {ChannelData} data any additional custom params
+ * @param {ChannelData} data any additional custom params
*
- * @return {Channel} Returns a new uninitialized channel
+ * @return {Channel} Returns a new uninitialized channel
*/
- constructor(
- client: StreamChat,
- type: string,
- id: string | undefined,
- data: ChannelData,
- ) {
+ constructor(client: StreamChat, type: string, id: string | undefined, data: ChannelData) {
const validTypeRe = /^[\w_-]+$/;
const validIDRe = /^[\w!_-]+$/;
@@ -136,7 +130,7 @@ export class Channel(this);
+ this.state = new ChannelState(this);
this.initialized = false;
this.offlineMode = false;
this.lastTypingEvent = null;
@@ -147,9 +141,9 @@ export class Channel}
+ * @return {StreamChat}
*/
- getClient(): StreamChat {
+ getClient(): StreamChat {
if (this.disconnected === true) {
throw Error(`You can't use a channel after client.disconnect() was called`);
}
@@ -169,7 +163,7 @@ export class Channel} message The Message object
+ * @param {Message} message The Message object
* @param {boolean} [options.skip_enrich_url] Do not try to enrich the URLs within message
* @param {boolean} [options.skip_push] Skip sending push notifications
* @param {boolean} [options.is_pending_message] DEPRECATED, please use `pending` instead.
@@ -177,10 +171,10 @@ export class Channel} [options.pending_message_metadata] Metadata for the pending message
* @param {boolean} [options.force_moderation] Apply force moderation for server-side requests
*
- * @return {Promise>} The Server Response
+ * @return {Promise} The Server Response
*/
- async sendMessage(message: Message, options?: SendMessageOptions) {
- return await this.getClient().post>(this._channelURL() + '/message', {
+ async sendMessage(message: Message, options?: SendMessageOptions) {
+ return await this.getClient().post(this._channelURL() + '/message', {
message,
...options,
});
@@ -190,17 +184,12 @@ export class Channel,
+ user?: UserResponse,
) {
return this.getClient().sendFile(`${this._channelURL()}/file`, uri, name, contentType, user);
}
- sendImage(
- uri: string | NodeJS.ReadableStream | File,
- name?: string,
- contentType?: string,
- user?: UserResponse,
- ) {
+ sendImage(uri: string | NodeJS.ReadableStream | File, name?: string, contentType?: string, user?: UserResponse) {
return this.getClient().sendFile(`${this._channelURL()}/image`, uri, name, contentType, user);
}
@@ -215,13 +204,13 @@ export class Channel} event for example {type: 'message.read'}
+ * @param {Event} event for example {type: 'message.read'}
*
- * @return {Promise>} The Server Response
+ * @return {Promise} The Server Response
*/
- async sendEvent(event: Event) {
+ async sendEvent(event: Event) {
this._checkInitialized();
- return await this.getClient().post>(this._channelURL() + '/event', {
+ return await this.getClient().post(this._channelURL() + '/event', {
event,
});
}
@@ -229,17 +218,17 @@ export class Channel | string} query search query or object MongoDB style filters
- * @param {{client_id?: string; connection_id?: string; query?: string; message_filter_conditions?: MessageFilters}} options Option object, {user_id: 'tommaso'}
+ * @param {MessageFilters | string} query search query or object MongoDB style filters
+ * @param {{client_id?: string; connection_id?: string; query?: string; message_filter_conditions?: MessageFilters}} options Option object, {user_id: 'tommaso'}
*
- * @return {Promise>} search messages response
+ * @return {Promise} search messages response
*/
async search(
- query: MessageFilters | string,
- options: SearchOptions & {
+ query: MessageFilters | string,
+ options: SearchOptions & {
client_id?: string;
connection_id?: string;
- message_filter_conditions?: MessageFilters;
+ message_filter_conditions?: MessageFilters;
message_options?: MessageOptions;
query?: string;
} = {},
@@ -248,10 +237,10 @@ export class Channel = {
- filter_conditions: { cid: this.cid } as ChannelFilters,
+ const payload: SearchPayload = {
+ filter_conditions: { cid: this.cid } as ChannelFilters,
...options,
- sort: options.sort ? normalizeQuerySort>(options.sort) : undefined,
+ sort: options.sort ? normalizeQuerySort(options.sort) : undefined,
};
if (typeof query === 'string') {
payload.query = query;
@@ -263,7 +252,7 @@ export class Channel>(this.getClient().baseURL + '/search', {
+ return await this.getClient().get(this.getClient().baseURL + '/search', {
payload,
});
}
@@ -271,56 +260,49 @@ export class Channel} filterConditions object MongoDB style filters
- * @param {MemberSort} [sort] Sort options, for instance [{created_at: -1}].
+ * @param {MemberFilters} filterConditions object MongoDB style filters
+ * @param {MemberSort} [sort] Sort options, for instance [{created_at: -1}].
* When using multiple fields, make sure you use array of objects to guarantee field order, for instance [{name: -1}, {created_at: 1}]
* @param {{ limit?: number; offset?: number }} [options] Option object, {limit: 10, offset:10}
*
- * @return {Promise>} Query Members response
+ * @return {Promise} Query Members response
*/
- async queryMembers(
- filterConditions: MemberFilters,
- sort: MemberSort = [],
- options: QueryMembersOptions = {},
- ) {
+ async queryMembers(filterConditions: MemberFilters, sort: MemberSort = [], options: QueryMembersOptions = {}) {
let id: string | undefined;
const type = this.type;
- let members: string[] | ChannelMemberResponse[] | undefined;
+ let members: string[] | ChannelMemberResponse[] | undefined;
if (this.id) {
id = this.id;
} else if (this.data?.members && Array.isArray(this.data.members)) {
members = this.data.members;
}
// Return a list of members
- return await this.getClient().get>(
- this.getClient().baseURL + '/members',
- {
- payload: {
- type,
- id,
- members,
- sort: normalizeQuerySort(sort),
- filter_conditions: filterConditions,
- ...options,
- },
+ return await this.getClient().get(this.getClient().baseURL + '/members', {
+ payload: {
+ type,
+ id,
+ members,
+ sort: normalizeQuerySort(sort),
+ filter_conditions: filterConditions,
+ ...options,
},
- );
+ });
}
/**
* partialUpdateMember - Partial update a member
*
* @param {string} user_id member user id
- * @param {PartialUpdateMember} updates
+ * @param {PartialUpdateMember} updates
*
- * @return {Promise>} Updated member
+ * @return {Promise} Updated member
*/
- async partialUpdateMember(user_id: string, updates: PartialUpdateMember) {
+ async partialUpdateMember(user_id: string, updates: PartialUpdateMember) {
if (!user_id) {
throw Error('Please specify the user id');
}
- return await this.getClient().patch>(
+ return await this.getClient().patch(
this._channelURL() + `/member/${encodeURIComponent(user_id)}`,
updates,
);
@@ -330,14 +312,14 @@ export class Channel} reaction the reaction object for instance {type: 'love'}
+ * @param {Reaction} reaction the reaction object for instance {type: 'love'}
* @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
*
- * @return {Promise>} The Server Response
+ * @return {Promise} The Server Response
*/
async sendReaction(
messageID: string,
- reaction: Reaction,
+ reaction: Reaction,
options?: { enforce_unique?: boolean; skip_push?: boolean },
) {
if (!messageID) {
@@ -346,7 +328,7 @@ export class Channel>(
+ return await this.getClient().post(
this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/reaction`,
{
reaction,
@@ -362,7 +344,7 @@ export class Channel>} The Server Response
+ * @return {Promise} The Server Response
*/
deleteReaction(messageID: string, reactionType: string, user_id?: string) {
this._checkInitialized();
@@ -375,27 +357,28 @@ export class Channel>(url, { user_id });
+ return this.getClient().delete(url, { user_id });
}
- return this.getClient().delete>(url, {});
+ return this.getClient().delete(url, {});
}
/**
* update - Edit the channel's custom properties
*
- * @param {ChannelData} channelData The object to update the custom properties of this channel with
- * @param {Message} [updateMessage] Optional message object for channel members notification
+ * @param {ChannelData} channelData The object to update the custom properties of this channel with
+ * @param {Message} [updateMessage] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
async update(
- channelData: Partial> | Partial> = {},
- updateMessage?: Message,
+ channelData: Partial = {},
+ updateMessage?: Message,
options?: ChannelUpdateOptions,
) {
// Strip out reserved names that will result in API errors.
- const reserved = [
+ // TODO: this needs to be typed better
+ const reserved: Exclude[] = [
'config',
'cid',
'created_by',
@@ -407,6 +390,7 @@ export class Channel {
delete channelData[key];
});
@@ -421,15 +405,12 @@ export class Channel} partial update request
+ * @param {PartialUpdateChannel} partial update request
*
- * @return {Promise>}
+ * @return {Promise}
*/
- async updatePartial(update: PartialUpdateChannel) {
- const data = await this.getClient().patch>(
- this._channelURL(),
- update,
- );
+ async updatePartial(update: PartialUpdateChannel) {
+ const data = await this.getClient().patch(this._channelURL(), update);
const areCapabilitiesChanged =
[...(data.channel.own_capabilities || [])].sort().join() !==
@@ -450,10 +431,10 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*/
async enableSlowMode(coolDownInterval: number) {
- const data = await this.getClient().post>(this._channelURL(), {
+ const data = await this.getClient().post(this._channelURL(), {
cooldown: coolDownInterval,
});
this.data = data.channel;
@@ -463,10 +444,10 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*/
async disableSlowMode() {
- const data = await this.getClient().post>(this._channelURL(), {
+ const data = await this.getClient().post(this._channelURL(), {
cooldown: 0,
});
this.data = data.channel;
@@ -478,61 +459,54 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*/
async delete(options: { hard_delete?: boolean } = {}) {
- return await this.getClient().delete>(this._channelURL(), {
+ return await this.getClient().delete(this._channelURL(), {
...options,
});
}
/**
* truncate - Removes all messages from the channel
- * @param {TruncateOptions} [options] Defines truncation options
- * @return {Promise>} The server response
+ * @param {TruncateOptions} [options] Defines truncation options
+ * @return {Promise} The server response
*/
- async truncate(options: TruncateOptions = {}) {
- return await this.getClient().post>(
- this._channelURL() + '/truncate',
- options,
- );
+ async truncate(options: TruncateOptions = {}) {
+ return await this.getClient().post(this._channelURL() + '/truncate', options);
}
/**
* acceptInvite - accept invitation to the channel
*
- * @param {InviteOptions} [options] The object to update the custom properties of this channel with
+ * @param {UpdateChannelOptions} [options] The object to update the custom properties of this channel with
*
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async acceptInvite(options: InviteOptions = {}) {
+ async acceptInvite(options: UpdateChannelOptions = {}) {
return await this._update({ accept_invite: true, ...options });
}
/**
* rejectInvite - reject invitation to the channel
*
- * @param {InviteOptions} [options] The object to update the custom properties of this channel with
+ * @param {UpdateChannelOptions} [options] The object to update the custom properties of this channel with
*
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async rejectInvite(options: InviteOptions = {}) {
+ async rejectInvite(options: UpdateChannelOptions = {}) {
return await this._update({ reject_invite: true, ...options });
}
/**
* addMembers - add members to the channel
*
- * @param {string[] | Array>} members An array of members to add to the channel
- * @param {Message} [message] Optional message object for channel members notification
+ * @param {string[] | Array} members An array of members to add to the channel
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async addMembers(
- members: string[] | Array>,
- message?: Message,
- options: ChannelUpdateOptions = {},
- ) {
+ async addMembers(members: string[] | Array, message?: Message, options: ChannelUpdateOptions = {}) {
return await this._update({ add_members: members, message, ...options });
}
@@ -540,11 +514,11 @@ export class Channel} [message] Optional message object for channel members notification
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async addModerators(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
+ async addModerators(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
return await this._update({ add_moderators: members, message, ...options });
}
@@ -552,13 +526,13 @@ export class Channel} [message] Optional message object for channel members notification
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
async assignRoles(
roles: { channel_role: Role; user_id: string }[],
- message?: Message,
+ message?: Message,
options: ChannelUpdateOptions = {},
) {
return await this._update({ assign_roles: roles, message, ...options });
@@ -567,14 +541,14 @@ export class Channel>} members An array of members to invite to the channel
- * @param {Message} [message] Optional message object for channel members notification
+ * @param {string[] | Array} members An array of members to invite to the channel
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
async inviteMembers(
- members: string[] | Array>,
- message?: Message,
+ members: string[] | Required>[],
+ message?: Message,
options: ChannelUpdateOptions = {},
) {
return await this._update({ invites: members, message, ...options });
@@ -584,11 +558,11 @@ export class Channel} [message] Optional message object for channel members notification
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async removeMembers(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
+ async removeMembers(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
return await this._update({ remove_members: members, message, ...options });
}
@@ -596,22 +570,22 @@ export class Channel} [message] Optional message object for channel members notification
+ * @param {Message} [message] Optional message object for channel members notification
* @param {ChannelUpdateOptions} [options] Option object, configuration to control the behavior while updating
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async demoteModerators(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
+ async demoteModerators(members: string[], message?: Message, options: ChannelUpdateOptions = {}) {
return await this._update({ demote_moderators: members, message, ...options });
}
/**
* _update - executes channel update request
* @param payload Object Update Channel payload
- * @return {Promise>} The server response
+ * @return {Promise} The server response
* TODO: introduce new type instead of Object in the next major update
*/
async _update(payload: Object) {
- const data = await this.getClient().post>(this._channelURL(), payload);
+ const data = await this.getClient().post(this._channelURL(), payload);
this.data = data.channel;
return data;
}
@@ -619,7 +593,7 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*
* example with expiration:
* await channel.mute({expiration: moment.duration(2, 'weeks')});
@@ -629,10 +603,10 @@ export class Channel>(
- this.getClient().baseURL + '/moderation/mute/channel',
- { channel_cid: this.cid, ...opts },
- );
+ return await this.getClient().post(this.getClient().baseURL + '/moderation/mute/channel', {
+ channel_cid: this.cid,
+ ...opts,
+ });
}
/**
@@ -653,7 +627,7 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*
* example:
* await channel.archives();
@@ -675,7 +649,7 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*
* example:
* await channel.unarchive();
@@ -697,7 +671,7 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*
* example:
* await channel.pin();
@@ -719,7 +693,7 @@ export class Channel>} The server response
+ * @return {Promise} The server response
*
* example:
* await channel.unpin();
@@ -756,7 +730,7 @@ export class Channel>(
+ return this.getClient().post(
this.getClient().baseURL + `/messages/${encodeURIComponent(messageID)}/action`,
{
message_id: messageID,
@@ -788,7 +762,7 @@ export class Channel);
+ } as Event);
}
}
@@ -806,7 +780,7 @@ export class Channel);
+ } as Event);
}
/**
@@ -816,7 +790,7 @@ export class Channel);
+ } as Event);
}
/**
@@ -826,7 +800,7 @@ export class Channel);
+ } as Event);
}
/**
@@ -844,7 +818,7 @@ export class Channel);
+ } as Event);
}
_isTypingIndicatorsEnabled(): boolean {
@@ -857,9 +831,9 @@ export class Channel['formatMessage']> | undefined} Description
+ * @return {ReturnType | undefined} Description
*/
- lastMessage(): FormatMessageResponse | undefined {
+ lastMessage(): FormatMessageResponse | undefined {
// get last 5 messages, sort, return the latest
// get a slice of the last 5
let min = this.state.latestMessages.length - 5;
@@ -878,17 +852,17 @@ export class Channel} data
- * @return {Promise | null>} Description
+ * @param {MarkReadOptions} data
+ * @return {Promise} Description
*/
- async markRead(data: MarkReadOptions = {}) {
+ async markRead(data: MarkReadOptions = {}) {
this._checkInitialized();
if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {
return Promise.resolve(null);
}
- return await this.getClient().post>(this._channelURL() + '/read', {
+ return await this.getClient().post(this._channelURL() + '/read', {
...data,
});
}
@@ -896,10 +870,10 @@ export class Channel} data
+ * @param {MarkUnreadOptions} data
* @return {APIResponse} An API response
*/
- async markUnread(data: MarkUnreadOptions) {
+ async markUnread(data: MarkUnreadOptions) {
this._checkInitialized();
if (!this.getConfig()?.read_events && !this.getClient()._isUsingServerAuth()) {
@@ -929,11 +903,11 @@ export class Channel} options additional options for the query endpoint
+ * @param {ChannelQueryOptions} options additional options for the query endpoint
*
- * @return {Promise>} The server response
+ * @return {Promise} The server response
*/
- async watch(options?: ChannelQueryOptions) {
+ async watch(options?: ChannelQueryOptions) {
const defaultOptions = {
state: true,
watch: true,
@@ -981,17 +955,17 @@ export class Channel; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
+ * @param {MessagePaginationOptions & { user?: UserResponse; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
*
- * @return {Promise>} A response with a list of messages
+ * @return {Promise} A response with a list of messages
*/
async getReplies(
parent_id: string,
- options: MessagePaginationOptions & { user?: UserResponse; user_id?: string },
+ options: MessagePaginationOptions & { user?: UserResponse; user_id?: string },
sort?: { created_at: AscDesc }[],
) {
const normalizedSort = sort ? normalizeQuerySort(sort) : undefined;
- const data = await this.getClient().get>(
+ const data = await this.getClient().get(
this.getClient().baseURL + `/messages/${encodeURIComponent(parent_id)}/replies`,
{
sort: normalizedSort,
@@ -1010,24 +984,21 @@ export class Channel; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
+ * @param {PinnedMessagePaginationOptions & { user?: UserResponse; user_id?: string }} options Pagination params, ie {limit:10, id_lte: 10}
* @param {PinnedMessagesSort} sort defines sorting direction of pinned messages
*
- * @return {Promise>} A response with a list of messages
+ * @return {Promise} A response with a list of messages
*/
async getPinnedMessages(
- options: PinnedMessagePaginationOptions & { user?: UserResponse; user_id?: string },
+ options: PinnedMessagePaginationOptions & { user?: UserResponse; user_id?: string },
sort: PinnedMessagesSort = [],
) {
- return await this.getClient().get>(
- this._channelURL() + '/pinned_messages',
- {
- payload: {
- ...options,
- sort: normalizeQuerySort(sort),
- },
+ return await this.getClient().get(this._channelURL() + '/pinned_messages', {
+ payload: {
+ ...options,
+ sort: normalizeQuerySort(sort),
},
- );
+ });
}
/**
@@ -1036,10 +1007,10 @@ export class Channel>} Server response
+ * @return {Promise} Server response
*/
getReactions(message_id: string, options: { limit?: number; offset?: number }) {
- return this.getClient().get>(
+ return this.getClient().get(
this.getClient().baseURL + `/messages/${encodeURIComponent(message_id)}/reactions`,
{
...options,
@@ -1052,10 +1023,10 @@ export class Channel>} Server response
+ * @return {Promise} Server response
*/
getMessagesById(messageIds: string[]) {
- return this.getClient().get>(this._channelURL() + '/messages', {
+ return this.getClient().get(this._channelURL() + '/messages', {
ids: messageIds.join(','),
});
}
@@ -1071,7 +1042,7 @@ export class Channel | MessageResponse) {
+ _countMessageAsUnread(message: FormatMessageResponse | MessageResponse) {
if (message.shadowed) return false;
if (message.silent) return false;
if (message.parent_id && !message.show_in_channel) return false;
@@ -1079,8 +1050,9 @@ export class Channel>} The Server Response
+ * @return {Promise} The Server Response
*
*/
- create = async (options?: ChannelQueryOptions) => {
+ create = async (options?: ChannelQueryOptions) => {
const defaultOptions = {
...options,
watch: false,
@@ -1150,15 +1122,12 @@ export class Channel} options The query options
+ * @param {ChannelQueryOptions} options The query options
* @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
*
- * @return {Promise>} Returns a query response
+ * @return {Promise} Returns a query response
*/
- async query(
- options?: ChannelQueryOptions,
- messageSetToAddToIfDoesNotExist: MessageSetType = 'current',
- ) {
+ async query(options?: ChannelQueryOptions, messageSetToAddToIfDoesNotExist: MessageSetType = 'current') {
// Make sure we wait for the connect promise if there is a pending one
await this.getClient().wsPromise;
@@ -1167,7 +1136,7 @@ export class Channel>(queryURL + '/query', {
+ const state = await this.getClient().post(queryURL + '/query', {
data: this._data,
state: true,
...options,
@@ -1214,7 +1183,7 @@ export class Channel} options
+ * @param {BanUserOptions} options
* @returns {Promise}
*/
- async banUser(targetUserID: string, options: BanUserOptions) {
+ async banUser(targetUserID: string, options: BanUserOptions) {
this._checkInitialized();
return await this.getClient().banUser(targetUserID, {
...options,
@@ -1301,10 +1270,10 @@ export class Channel} options
+ * @param {BanUserOptions} options
* @returns {Promise}
*/
- async shadowBan(targetUserID: string, options: BanUserOptions) {
+ async shadowBan(targetUserID: string, options: BanUserOptions) {
this._checkInitialized();
return await this.getClient().shadowBan(targetUserID, {
...options,
@@ -1358,15 +1327,12 @@ export class Channel {console.log(event.type)})
*
- * @param {EventHandler | EventTypes} callbackOrString The event type to listen for (optional)
- * @param {EventHandler} [callbackOrNothing] The callback to call
+ * @param {EventHandler | EventTypes} callbackOrString The event type to listen for (optional)
+ * @param {EventHandler} [callbackOrNothing] The callback to call
*/
- on(eventType: EventTypes, callback: EventHandler): { unsubscribe: () => void };
- on(callback: EventHandler): { unsubscribe: () => void };
- on(
- callbackOrString: EventHandler | EventTypes,
- callbackOrNothing?: EventHandler,
- ): { unsubscribe: () => void } {
+ on(eventType: EventTypes, callback: EventHandler): { unsubscribe: () => void };
+ on(callback: EventHandler): { unsubscribe: () => void };
+ on(callbackOrString: EventHandler | EventTypes, callbackOrNothing?: EventHandler): { unsubscribe: () => void } {
const key = callbackOrNothing ? (callbackOrString as string) : 'all';
const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;
if (!(key in this.listeners)) {
@@ -1395,12 +1361,9 @@ export class Channel): void;
- off(callback: EventHandler): void;
- off(
- callbackOrString: EventHandler | EventTypes,
- callbackOrNothing?: EventHandler,
- ): void {
+ off(eventType: EventTypes, callback: EventHandler): void;
+ off(callback: EventHandler): void;
+ off(callbackOrString: EventHandler | EventTypes, callbackOrNothing?: EventHandler): void {
const key = callbackOrNothing ? (callbackOrString as string) : 'all';
const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;
if (!(key in this.listeners)) {
@@ -1415,7 +1378,7 @@ export class Channel) {
+ _handleChannelEvent(event: Event) {
const channel = this;
this._client.logger(
'info',
@@ -1538,8 +1501,7 @@ export class Channel {
- if (truncatedAt > +createdAt)
- channelState.removePinnedMessage({ id } as MessageResponse);
+ if (truncatedAt > +createdAt) channelState.removePinnedMessage({ id } as MessageResponse);
});
} else {
channelState.clearMessages();
@@ -1666,7 +1628,7 @@ export class Channel) => {
+ _callChannelListeners = (event: Event) => {
const channel = this;
// gather and call the listeners
const listeners = [];
@@ -1706,10 +1668,7 @@ export class Channel,
- messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',
- ) {
+ _initializeState(state: ChannelAPIResponse, messageSetToAddToIfDoesNotExist: MessageSetType = 'latest') {
const { state: clientState, user, userID } = this.getClient();
// add the members and users
@@ -1786,7 +1745,7 @@ export class Channel) {
+ _extendEventWithOwnReactions(event: Event) {
if (!event.message) {
return;
}
@@ -1800,7 +1759,7 @@ export class Channel[];
+ members: ChannelMemberResponse[];
/**
* If set to `true` then `ChannelState.members` will be overriden with the newly
* provided `members`, setting this property to `false` will merge current `ChannelState.members`
@@ -1809,7 +1768,7 @@ export class Channel