UNPKG

stream-chat

Version:

JS SDK for the Stream Chat API

1,866 lines (1,686 loc) 112 kB
import type { EVENT_MAP } from './events'; import type { Channel } from './channel'; import type { AxiosRequestConfig, AxiosResponse } from 'axios'; import type { StableWSConnection } from './connection'; import type { Role } from './permissions'; import type { CustomAttachmentData, CustomChannelData, CustomCommandData, CustomEventData, CustomMemberData, CustomMessageData, CustomPollData, CustomPollOptionData, CustomReactionData, CustomThreadData, CustomUserData, } from './custom_types'; import type { NotificationManager } from './notifications'; import type { RESERVED_UPDATED_MESSAGE_FIELDS } from './constants'; /** * Utility Types */ export type Readable<T> = { [key in keyof T]: T[key]; } & {}; export type ArrayOneOrMore<T> = { 0: T; } & Array<T>; export type ArrayTwoOrMore<T> = { 0: T; 1: T; } & Array<T>; export type KnownKeys<T> = { [K in keyof T]: string extends K ? never : number extends K ? never : K; } extends { [_ in keyof T]: infer U } ? U : never; export type RequireAtLeastOne<T> = { [K in keyof T]-?: Required<Pick<T, K>> & Partial<Omit<T, K>>; }[keyof T]; export type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & { [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>; }[Keys]; export type PartializeKeys<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>; /* Unknown Record */ export type UR = Record<string, unknown>; export type UnknownType = UR; //alias to avoid breaking change export type Unpacked<T> = T extends (infer U)[] ? U // eslint-disable-next-line @typescript-eslint/no-explicit-any : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T; /** * Response Types */ export type APIResponse = { duration: string; }; export type TranslateResponse = { language: string; translated_text: string; }; export type AppSettingsAPIResponse = APIResponse & { app?: { // TODO // eslint-disable-next-line @typescript-eslint/no-explicit-any call_types: any; channel_configs: Record< string, { reminders: boolean; automod?: ChannelConfigAutomod; automod_behavior?: ChannelConfigAutomodBehavior; automod_thresholds?: ChannelConfigAutomodThresholds; blocklist_behavior?: ChannelConfigAutomodBehavior; commands?: CommandVariants[]; connect_events?: boolean; created_at?: string; custom_events?: boolean; delivery_events?: boolean; mark_messages_pending?: boolean; max_message_length?: number; message_retention?: string; mutes?: boolean; name?: string; polls?: boolean; push_notifications?: boolean; quotes?: boolean; reactions?: boolean; read_events?: boolean; replies?: boolean; search?: boolean; typing_events?: boolean; updated_at?: string; uploads?: boolean; url_enrichment?: boolean; user_message_reminders?: boolean; } >; reminders_interval: number; async_moderation_config?: AsyncModerationOptions; async_url_enrich_enabled?: boolean; auto_translation_enabled?: boolean; before_message_send_hook_url?: string; campaign_enabled?: boolean; cdn_expiration_seconds?: number; custom_action_handler_url?: string; datadog_info?: { api_key: string; site: string; enabled?: boolean; }; disable_auth_checks?: boolean; disable_permissions_checks?: boolean; enforce_unique_usernames?: 'no' | 'app' | 'team'; event_hooks?: Array<EventHook>; file_upload_config?: FileUploadConfig; geofences?: Array<{ country_codes: Array<string>; description: string; name: string; type: string; }>; grants?: Record<string, string[]>; image_moderation_enabled?: boolean; image_upload_config?: FileUploadConfig; multi_tenant_enabled?: boolean; name?: string; organization?: string; permission_version?: string; policies?: Record<string, Policy[]>; poll_enabled?: boolean; push_notifications?: { offline_only: boolean; version: string; apn?: APNConfig; firebase?: FirebaseConfig; huawei?: HuaweiConfig; providers?: PushProviderConfig[]; xiaomi?: XiaomiConfig; }; revoke_tokens_issued_before?: string | null; search_backend?: 'disabled' | 'elasticsearch' | 'postgres'; sns_key?: string; sns_secret?: string; sns_topic_arn?: string; sqs_key?: string; sqs_secret?: string; sqs_url?: string; suspended?: boolean; suspended_explanation?: string; user_search_disallowed_roles?: string[] | null; video_provider?: string; webhook_events?: Array<string>; webhook_url?: string; }; }; export type ModerationResult = { action: string; created_at: string; message_id: string; updated_at: string; user_bad_karma: boolean; user_karma: number; blocked_word?: string; blocklist_name?: string; moderated_by?: string; }; export type AutomodDetails = { action?: string; image_labels?: Array<string>; original_message_type?: string; result?: ModerationResult; }; export type FlagDetails = { automod?: AutomodDetails; }; export type Flag = { created_at: string; created_by_automod: boolean; updated_at: string; details?: FlagDetails; target_message?: MessageResponse; target_user?: UserResponse; user?: UserResponse; }; export type FlagsResponse = APIResponse & { flags?: Array<Flag>; }; export type MessageFlagsResponse = APIResponse & { flags?: Array<{ message: MessageResponse; user: UserResponse; approved_at?: string; created_at?: string; created_by_automod?: boolean; moderation_result?: ModerationResult; rejected_at?: string; reviewed_at?: string; reviewed_by?: UserResponse; updated_at?: string; }>; }; export type FlagReport = { flags_count: number; id: string; message: MessageResponse; user: UserResponse; created_at?: string; details?: FlagDetails; first_reporter?: UserResponse; review_result?: string; reviewed_at?: string; reviewed_by?: UserResponse; updated_at?: string; }; export type FlagReportsResponse = APIResponse & { flag_reports: Array<FlagReport>; }; export type ReviewFlagReportResponse = APIResponse & { flag_report: FlagReport; }; export type BannedUsersResponse = APIResponse & { bans?: Array<{ user: UserResponse; banned_by?: UserResponse; channel?: ChannelResponse; expires?: string; ip_ban?: boolean; reason?: string; timeout?: number; }>; }; export type BlockListResponse = BlockList & { created_at?: string; type?: string; updated_at?: string; }; export type ChannelResponse = CustomChannelData & { cid: string; disabled: boolean; frozen: boolean; id: string; type: string; blocked?: boolean; auto_translation_enabled?: boolean; auto_translation_language?: TranslationLanguages; hide_messages_before?: string; config?: ChannelConfigWithInfo; cooldown?: number; created_at?: string; created_by?: UserResponse | null; created_by_id?: string; deleted_at?: string; hidden?: boolean; invites?: string[]; joined?: boolean; last_message_at?: string; member_count?: number; members?: ChannelMemberResponse[]; message_count?: number; muted?: boolean; mute_expires_at?: string; own_capabilities?: string[]; team?: string; truncated_at?: string; truncated_by?: UserResponse; truncated_by_id?: string; updated_at?: string; }; export type QueryReactionsOptions = Pager; export type QueryReactionsAPIResponse = APIResponse & { reactions: ReactionResponse[]; next?: string; }; export type QueryChannelsAPIResponse = APIResponse & { channels: Omit<ChannelAPIResponse, keyof APIResponse>[]; }; export type QueryChannelAPIResponse = APIResponse & ChannelAPIResponse; export type ChannelAPIResponse = { channel: ChannelResponse; members: ChannelMemberResponse[]; messages: MessageResponse[]; pinned_messages: MessageResponse[]; draft?: DraftResponse; hidden?: boolean; membership?: ChannelMemberResponse | null; pending_messages?: PendingMessageResponse[]; push_preferences?: PushPreference; read?: ReadResponse[]; threads?: ThreadResponse[]; watcher_count?: number; watchers?: UserResponse[]; active_live_locations?: SharedLocationResponse[]; }; export type ChannelUpdateOptions = { hide_history?: boolean; skip_push?: boolean; }; export type ChannelMemberAPIResponse = APIResponse & { members: ChannelMemberResponse[]; }; export type ChannelMemberUpdates = CustomMemberData & { archived?: boolean; channel_role?: Role; pinned?: boolean; }; export type ChannelMemberResponse = CustomMemberData & { archived_at?: string | null; ban_expires?: string; banned?: boolean; channel_role?: Role; created_at?: string; invite_accepted_at?: string; invite_rejected_at?: string; invited?: boolean; is_moderator?: boolean; notifications_muted?: boolean; pinned_at?: string | null; role?: string; shadow_banned?: boolean; status?: InviteStatus; updated_at?: string; user?: UserResponse; user_id?: string; }; export type PartialUpdateMemberAPIResponse = APIResponse & { channel_member: ChannelMemberResponse; }; export type CheckPushResponse = APIResponse & { device_errors?: { [deviceID: string]: { error_message?: string; provider?: PushProvider; provider_name?: string; }; }; general_errors?: string[]; rendered_apn_template?: string; rendered_firebase_template?: string; rendered_message?: {}; skip_devices?: boolean; }; export type CheckSQSResponse = APIResponse & { status: string; data?: {}; error?: string; }; export type CheckSNSResponse = APIResponse & { status: string; data?: {}; error?: string; }; export type CommandResponse = Partial<CreatedAtUpdatedAt> & { args?: string; description?: string; name?: CommandVariants; set?: CommandVariants; }; export type ConnectAPIResponse = Promise<void | ConnectionOpen>; export type CreateChannelResponse = APIResponse & Omit<CreateChannelOptions, 'client_id' | 'connection_id'> & { created_at: string; updated_at: string; grants?: Record<string, string[]>; }; export type CreateCommandResponse = APIResponse & { command: CreateCommandOptions & CreatedAtUpdatedAt; }; export type DeleteChannelAPIResponse = APIResponse & { channel: ChannelResponse; }; export type DeleteCommandResponse = APIResponse & { name?: CommandVariants; }; export type EventAPIResponse = APIResponse & { event: Event; }; export type ExportChannelResponse = { task_id: string; }; export type ExportUsersResponse = { task_id: string; }; export type ExportChannelStatusResponse = { created_at?: string; error?: {}; result?: {}; updated_at?: string; }; export type FlagMessageResponse = APIResponse & { flag: { created_at: string; created_by_automod: boolean; target_message_id: string; updated_at: string; user: UserResponse; approved_at?: string; channel_cid?: string; details?: object; // Any JSON message_user_id?: string; rejected_at?: string; reviewed_at?: string; reviewed_by?: string; }; review_queue_item_id?: string; }; export type FlagUserResponse = APIResponse & { flag: { created_at: string; created_by_automod: boolean; target_user: UserResponse; updated_at: string; user: UserResponse; approved_at?: string; details?: object; // Any JSON rejected_at?: string; reviewed_at?: string; reviewed_by?: string; }; review_queue_item_id?: string; }; export type LocalMessageBase = Omit< MessageResponseBase, 'created_at' | 'deleted_at' | 'pinned_at' | 'status' | 'updated_at' > & { created_at: Date; deleted_at: Date | null; pinned_at: Date | null; status: string; updated_at: Date; }; export type LocalMessage = LocalMessageBase & { error?: ErrorFromResponse<APIErrorResponse>; quoted_message?: LocalMessageBase; }; /** * @deprecated in favor of LocalMessage */ export type FormatMessageResponse = LocalMessage; export type GetCommandResponse = APIResponse & CreateCommandOptions & CreatedAtUpdatedAt; export type GetMessageAPIResponse = SendMessageAPIResponse; export interface ThreadResponse extends CustomThreadData { // FIXME: according to OpenAPI, `channel` could be undefined but since cid is provided I'll asume that it's wrong channel: ChannelResponse; channel_cid: string; created_at: string; created_by_user_id: string; latest_replies: Array<MessageResponse>; parent_message: MessageResponse; parent_message_id: string; title: string; updated_at: string; active_participant_count?: number; created_by?: UserResponse; deleted_at?: string; draft?: DraftResponse; last_message_at?: string; participant_count?: number; read?: Array<ReadResponse>; reply_count?: number; thread_participants?: Array<{ channel_cid: string; created_at: string; last_read_at: string; last_thread_message_at?: string; left_thread_at?: string; thread_id?: string; user?: UserResponse; user_id?: string; }>; // TODO: when moving to API v2 we should do this instead // custom: CustomThreadType; } // TODO: Figure out a way to strongly type set and unset. export type PartialThreadUpdate = { set?: Partial<Record<string, unknown>>; unset?: Array<string>; }; export type QueryThreadsOptions = { filter?: ThreadFilters; limit?: number; member_limit?: number; next?: string; participant_limit?: number; reply_limit?: number; sort?: ThreadSort; watch?: boolean; }; export type QueryThreadsAPIResponse = APIResponse & { threads: ThreadResponse[]; next?: string; }; export type GetThreadOptions = { member_limit?: number; participant_limit?: number; reply_limit?: number; watch?: boolean; }; export type GetThreadAPIResponse = APIResponse & { thread: ThreadResponse; }; export type GetMultipleMessagesAPIResponse = APIResponse & { messages: MessageResponse[]; }; export type GetRateLimitsResponse = APIResponse & { android?: RateLimitsMap; ios?: RateLimitsMap; server_side?: RateLimitsMap; web?: RateLimitsMap; }; export enum Product { Chat = 'chat', Video = 'video', Moderation = 'moderation', Feeds = 'feeds', } export type HookEvent = { name: string; description: string; products: Product[]; }; export type GetHookEventsResponse = APIResponse & { events: HookEvent[]; }; export type GetReactionsAPIResponse = APIResponse & { reactions: ReactionResponse[]; }; export type GetRepliesAPIResponse = APIResponse & { messages: MessageResponse[]; }; export type GetUnreadCountAPIResponse = APIResponse & { channel_type: { channel_count: number; channel_type: string; unread_count: number; }[]; channels: { channel_id: string; last_read: string; unread_count: number; }[]; threads: { last_read: string; last_read_message_id: string; parent_message_id: string; unread_count: number; }[]; total_unread_count: number; total_unread_threads_count: number; total_unread_count_by_team?: Record<string, number>; }; export type ChatLevelPushPreference = 'all' | 'none' | 'mentions' | (string & {}); export type PushPreference = { callLevel?: 'all' | 'none' | (string & {}); chatLevel?: ChatLevelPushPreference; disabledUntil?: string; // snooze till this time removeDisable?: boolean; // Temporary flag for resetting disabledUntil }; export type ChannelPushPreference = { chatLevel?: ChatLevelPushPreference; // "all", "none", "mentions", or other custom strings disabledUntil?: string; removeDisable?: boolean; // Temporary flag for resetting disabledUntil }; export type UpsertPushPreferencesResponse = APIResponse & { // Mapping of user IDs to their push preferences userChannelPreferences: Record<string, Record<string, ChannelPushPreference>>; userPreferences: Record<string, PushPreference>; // Mapping of user -> channel id -> push preferences }; export type GetUnreadCountBatchAPIResponse = APIResponse & { counts_by_user: { [userId: string]: GetUnreadCountAPIResponse }; }; export type ListChannelResponse = APIResponse & { channel_types: Record< string, Omit<CreateChannelOptions, 'client_id' | 'connection_id' | 'commands'> & { commands: CommandResponse[]; created_at: string; updated_at: string; grants?: Record<string, string[]>; } >; }; export type ListChannelTypesAPIResponse = ListChannelResponse; export type ListCommandsResponse = APIResponse & { commands: Array<CreateCommandOptions & Partial<CreatedAtUpdatedAt>>; }; export type MuteChannelAPIResponse = APIResponse & { channel_mute: ChannelMute; own_user: OwnUserResponse; channel_mutes?: ChannelMute[]; mute?: MuteResponse; }; export type MessageResponse = MessageResponseBase & { quoted_message?: MessageResponseBase; }; export type MessageResponseBase = MessageBase & { type: MessageLabel; args?: string; before_message_send_failed?: boolean; channel?: ChannelResponse; cid?: string; command?: string; command_info?: { name?: string }; created_at?: string; deleted_at?: string; deleted_reply_count?: number; i18n?: RequireAtLeastOne<Record<`${TranslationLanguages}_text`, string>> & { language: TranslationLanguages; }; latest_reactions?: ReactionResponse[]; member?: ChannelMemberResponse; mentioned_users?: UserResponse[]; message_text_updated_at?: string; moderation?: ModerationResponse; // present only with Moderation v2 moderation_details?: ModerationDetailsResponse; // present only with Moderation v1 own_reactions?: ReactionResponse[] | null; pin_expires?: string | null; pinned_at?: string | null; pinned_by?: UserResponse | null; poll?: PollResponse; reaction_counts?: { [key: string]: number } | null; reaction_groups?: { [key: string]: ReactionGroupResponse } | null; reaction_scores?: { [key: string]: number } | null; reminder?: ReminderResponseBase; reply_count?: number; shadowed?: boolean; shared_location?: SharedLocationResponse; status?: string; thread_participants?: UserResponse[]; updated_at?: string; deleted_for_me?: boolean; }; export type ReactionGroupResponse = { count: number; sum_scores: number; first_reaction_at?: string; last_reaction_at?: string; }; export type ModerationDetailsResponse = { action: 'MESSAGE_RESPONSE_ACTION_BOUNCE' | (string & {}); error_msg: string; harms: ModerationHarmResponse[]; original_text: string; }; export type ModerationHarmResponse = { name: string; phrase_list_ids: number[]; }; export type ModerationAction = 'bounce' | 'flag' | 'remove' | 'shadow'; export type ModerationResponse = { action: ModerationAction; original_text: string; }; export type MuteResponse = { user: UserResponse; created_at?: string; expires?: string; target?: UserResponse; updated_at?: string; }; export type MuteUserResponse = APIResponse & { mute?: MuteResponse; mutes?: Array<Mute>; own_user?: OwnUserResponse; }; export type BlockUserAPIResponse = APIResponse & { blocked_at: string; blocked_by_user_id: string; blocked_user_id: string; }; export type GetBlockedUsersAPIResponse = APIResponse & { blocks: BlockedUserDetails[]; }; export type BlockedUserDetails = APIResponse & { blocked_user: UserResponse; blocked_user_id: string; created_at: string; user: UserResponse; user_id: string; }; export type OwnUserBase = { channel_mutes: ChannelMute[]; devices: Device[]; mutes: Mute[]; total_unread_count: number; unread_channels: number; unread_count: number; unread_threads: number; invisible?: boolean; privacy_settings?: PrivacySettings; push_preferences?: PushPreference; roles?: string[]; }; export type OwnUserResponse = UserResponse & OwnUserBase; export type PartialUpdateChannelAPIResponse = APIResponse & { channel: ChannelResponse; members: ChannelMemberResponse[]; }; export type PermissionAPIResponse = APIResponse & { permission?: PermissionAPIObject; }; export type PermissionsAPIResponse = APIResponse & { permissions?: PermissionAPIObject[]; }; export type ReactionAPIResponse = APIResponse & { message: MessageResponse; reaction: ReactionResponse; }; export type ReactionResponse = Reaction & { created_at: string; message_id: string; updated_at: string; }; export type ReadResponse = { last_read: string; user: UserResponse; last_read_message_id?: string; unread_messages?: number; last_delivered_at?: string; last_delivered_message_id?: string; }; export type SearchAPIResponse = APIResponse & { results: { message: MessageResponse; }[]; next?: string; previous?: string; results_warning?: SearchWarning | null; }; export type SearchWarning = { channel_search_cids: string[]; channel_search_count: number; warning_code: number; warning_description: string; }; // Thumb URL(thumb_url) is added considering video attachments as the backend will return the thumbnail in the response. export type SendFileAPIResponse = APIResponse & { file: string; thumb_url?: string }; export type SendMessageAPIResponse = APIResponse & { message: MessageResponse; pending_message_metadata?: Record<string, string> | null; }; export type SyncResponse = APIResponse & { events: Event[]; inaccessible_cids?: string[]; }; export type TruncateChannelAPIResponse = APIResponse & { channel: ChannelResponse; message?: MessageResponse; }; export type UpdateChannelAPIResponse = APIResponse & { channel: ChannelResponse; members: ChannelMemberResponse[]; message?: MessageResponse; }; export type UpdateChannelResponse = APIResponse & Omit<CreateChannelOptions, 'client_id' | 'connection_id'> & { created_at: string; updated_at: string; }; export type UpdateCommandResponse = APIResponse & { command: UpdateCommandOptions & CreatedAtUpdatedAt & { name: CommandVariants; }; }; export type UpdateMessageAPIResponse = APIResponse & { message: MessageResponse; }; export type UsersAPIResponse = APIResponse & { users: Array<UserResponse>; }; export type UpdateUsersAPIResponse = APIResponse & { users: { [key: string]: UserResponse }; }; export type UserResponse = CustomUserData & { id: string; anon?: boolean; banned?: boolean; blocked_user_ids?: string[]; created_at?: string; deactivated_at?: string; deleted_at?: string; image?: string; language?: TranslationLanguages | ''; last_active?: string; name?: string; notifications_muted?: boolean; online?: boolean; privacy_settings?: PrivacySettings; push_notifications?: PushNotificationSettings; revoke_tokens_issued_before?: string; role?: string; shadow_banned?: boolean; teams?: string[]; teams_role?: TeamsRole; updated_at?: string; username?: string; avg_response_time?: number; }; export type TeamsRole = { [team: string]: string }; export type PrivacySettings = { read_receipts?: { enabled?: boolean; }; typing_indicators?: { enabled?: boolean; }; delivery_receipts?: { enabled?: boolean; }; }; export type PushNotificationSettings = { disabled?: boolean; disabled_until?: string | null; }; /** * Option Types */ export type MessageFlagsPaginationOptions = { limit?: number; offset?: number; }; export type FlagsPaginationOptions = { limit?: number; offset?: number; }; export type FlagReportsPaginationOptions = { limit?: number; offset?: number; }; export type ReviewFlagReportOptions = { review_details?: object; user_id?: string; }; export type BannedUsersPaginationOptions = Omit< PaginationOptions, 'id_gt' | 'id_gte' | 'id_lt' | 'id_lte' > & { exclude_expired_bans?: boolean; }; export type BanUserOptions = UnBanUserOptions & { banned_by?: UserResponse; banned_by_id?: string; ip_ban?: boolean; reason?: string; timeout?: number; delete_messages?: MessageDeletionStrategy; }; export type ChannelOptions = { limit?: number; member_limit?: number; message_limit?: number; offset?: number; presence?: boolean; state?: boolean; user_id?: string; watch?: boolean; }; export type ChannelQueryOptions = { client_id?: string; connection_id?: string; created_by?: UserResponse | null; created_by_id?: UserResponse['id']; data?: ChannelResponse; hide_for_creator?: boolean; members?: PaginationOptions; messages?: MessagePaginationOptions; presence?: boolean; state?: boolean; watch?: boolean; watchers?: PaginationOptions; }; export type ChannelStateOptions = { offlineMode?: boolean; skipInitialization?: string[]; skipHydration?: boolean; }; export type CreateChannelOptions = { automod?: ChannelConfigAutomod; automod_behavior?: ChannelConfigAutomodBehavior; automod_thresholds?: ChannelConfigAutomodThresholds; blocklist?: string; blocklist_behavior?: ChannelConfigAutomodBehavior; client_id?: string; commands?: CommandVariants[]; connect_events?: boolean; connection_id?: string; custom_events?: boolean; delivery_events?: boolean; grants?: Record<string, string[]>; mark_messages_pending?: boolean; max_message_length?: number; message_retention?: string; mutes?: boolean; name?: string; permissions?: PermissionObject[]; polls?: boolean; push_notifications?: boolean; quotes?: boolean; reactions?: boolean; read_events?: boolean; reminders?: boolean; replies?: boolean; search?: boolean; skip_last_msg_update_for_system_msgs?: boolean; typing_events?: boolean; uploads?: boolean; url_enrichment?: boolean; user_message_reminders?: boolean; }; export type CreateCommandOptions = { description: string; name: CommandVariants; args?: string; set?: CommandVariants; }; export type CustomPermissionOptions = { action: string; condition: object; id: string; name: string; description?: string; owner?: boolean; same_team?: boolean; }; export type DeactivateUsersOptions = { created_by_id?: string; mark_messages_deleted?: boolean; }; export type NewMemberPayload = CustomMemberData & Pick<ChannelMemberResponse, 'user_id' | 'channel_role'>; export type Thresholds = Record< 'explicit' | 'spam' | 'toxic', Partial<{ block: number; flag: number }> >; export type BlockListOptions = { behavior: BlocklistBehavior; blocklist: string; }; export type PolicyRequest = { action: 'Deny' | 'Allow' | (string & {}); /** * @description User-friendly policy name */ name: string; /** * @description Whether policy applies to resource owner or not */ owner: boolean; priority: number; /** * @description List of resources to apply policy to */ resources: string[]; /** * @description List of roles to apply policy to */ roles: string[]; }; export type Automod = 'disabled' | 'simple' | 'AI' | (string & {}); export type AutomodBehavior = 'flag' | 'block' | 'shadow_block' | (string & {}); export type BlocklistBehavior = AutomodBehavior; export type Command = { args: string; description: string; name: string; set: string; created_at?: string; updated_at?: string; }; export type UpdateChannelTypeRequest = // these three properties are required in OpenAPI spec but omitted in some QA tests Partial<{ automod: Automod; automod_behavior: AutomodBehavior; max_message_length: number; }> & { allowed_flag_reasons?: string[]; automod_thresholds?: Thresholds; blocklist?: string; blocklist_behavior?: BlocklistBehavior; blocklists?: BlockListOptions[]; commands?: CommandVariants[]; connect_events?: boolean; custom_events?: boolean; delivery_events?: boolean; grants?: Record<string, string[]>; mark_messages_pending?: boolean; mutes?: boolean; partition_size?: number; /** * @example 24h */ partition_ttl?: string | null; permissions?: PolicyRequest[]; polls?: boolean; push_notifications?: boolean; quotes?: boolean; reactions?: boolean; read_events?: boolean; reminders?: boolean; replies?: boolean; search?: boolean; skip_last_msg_update_for_system_msgs?: boolean; typing_events?: boolean; uploads?: boolean; url_enrichment?: boolean; count_messages?: boolean; }; export type UpdateChannelTypeResponse = { automod: Automod; automod_behavior: AutomodBehavior; commands: CommandVariants[]; connect_events: boolean; created_at: string; custom_events: boolean; delivery_events: boolean; duration: string; grants: Record<string, string[]>; mark_messages_pending: boolean; max_message_length: number; mutes: boolean; name: string; permissions: PolicyRequest[]; polls: boolean; push_notifications: boolean; quotes: boolean; reactions: boolean; read_events: boolean; reminders: boolean; replies: boolean; search: boolean; skip_last_msg_update_for_system_msgs: boolean; typing_events: boolean; updated_at: string; uploads: boolean; url_enrichment: boolean; allowed_flag_reasons?: string[]; automod_thresholds?: Thresholds; blocklist?: string; blocklist_behavior?: BlocklistBehavior; blocklists?: BlockListOptions[]; partition_size?: number; partition_ttl?: string; count_messages?: boolean; }; export type GetChannelTypeResponse = { automod: Automod; automod_behavior: AutomodBehavior; commands: Command[]; connect_events: boolean; created_at: string; custom_events: boolean; delivery_events: boolean; duration: string; grants: Record<string, string[]>; mark_messages_pending: boolean; max_message_length: number; mutes: boolean; name: string; permissions: PolicyRequest[]; polls: boolean; push_notifications: boolean; quotes: boolean; reactions: boolean; read_events: boolean; reminders: boolean; replies: boolean; search: boolean; skip_last_msg_update_for_system_msgs: boolean; typing_events: boolean; updated_at: string; uploads: boolean; url_enrichment: boolean; allowed_flag_reasons?: string[]; automod_thresholds?: Thresholds; blocklist?: string; blocklist_behavior?: BlocklistBehavior; blocklists?: BlockListOptions[]; partition_size?: number; partition_ttl?: string; count_messages?: boolean; }; export type UpdateChannelOptions = Partial<{ accept_invite: boolean; add_members: string[]; add_moderators: string[]; client_id: string; connection_id: string; data: Omit<ChannelResponse, 'id' | 'cid'>; demote_moderators: string[]; invites: string[]; message: MessageResponse; reject_invite: boolean; remove_members: string[]; user: UserResponse; user_id: string; }>; export type MarkChannelsReadOptions = { client_id?: string; connection_id?: string; read_by_channel?: Record<string, string>; user?: UserResponse; user_id?: string; }; export type MarkReadOptions = { client_id?: string; connection_id?: string; thread_id?: string; user?: UserResponse; user_id?: string; }; export type MarkUnreadOptions = { client_id?: string; connection_id?: string; message_id?: string; thread_id?: string; user?: UserResponse; user_id?: string; }; export type DeliveredMessageConfirmation = { cid: string; id: string; parent_id?: string; // todo: should we include parent_id if thread delivery receipts are not yet supported? }; export type MarkDeliveredOptions = { latest_delivered_messages: DeliveredMessageConfirmation[]; user?: UserResponse; user_id?: string; }; export type MuteUserOptions = { client_id?: string; connection_id?: string; id?: string; reason?: string; target_user_id?: string; timeout?: number; type?: string; user?: UserResponse; user_id?: string; }; export type PaginationOptions = { created_at_after?: string | Date; created_at_after_or_equal?: string | Date; created_at_before?: string | Date; created_at_before_or_equal?: string | Date; id_gt?: string; id_gte?: string; id_lt?: string; id_lte?: string; limit?: number; offset?: number; // should be avoided with channel.query() }; export type MessagePaginationOptions = PaginationOptions & { created_at_around?: string | Date; id_around?: string; }; export type PinnedMessagePaginationOptions = { id_around?: string; id_gt?: string; id_gte?: string; id_lt?: string; id_lte?: string; limit?: number; offset?: number; pinned_at_after?: string | Date; pinned_at_after_or_equal?: string | Date; pinned_at_around?: string | Date; pinned_at_before?: string | Date; pinned_at_before_or_equal?: string | Date; }; export type QueryMembersOptions = { // Pagination option: select members created after the date (RFC399) created_at_after?: string; // Pagination option: select members created after or equal the date (RFC399) created_at_after_or_equal?: string; // Pagination option: select members created before the date (RFC399) created_at_before?: string; // Pagination option: select members created before or equal the date (RFC399) created_at_before_or_equal?: string; // Number of members to return, default 100 limit?: number; // Offset (max is 1000) offset?: number; // Pagination option: excludes members with ID less or equal the value user_id_gt?: string; // Pagination option: excludes members with ID less than the value user_id_gte?: string; // Pagination option: excludes members with ID greater or equal the value user_id_lt?: string; // Pagination option: excludes members with ID greater than the value user_id_lte?: string; }; export type ReactivateUserOptions = { created_by_id?: string; name?: string; restore_messages?: boolean; }; export type ReactivateUsersOptions = { created_by_id?: string; restore_messages?: boolean; }; export type SearchOptions = { limit?: number; next?: string; offset?: number; sort?: SearchMessageSort; }; export type StreamChatOptions = AxiosRequestConfig & { /** * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side. */ allowServerSideConnect?: boolean; axiosRequestConfig?: AxiosRequestConfig; /** * Base url to use for API * such as https://chat-proxy-dublin.stream-io-api.com */ baseURL?: string; browser?: boolean; device?: BaseDeviceFields; /** * Disables the hydration of all caches within the JS Client. This includes this.activeChannels, * this.polls.pollCache and this.config. * It is mainly meant to be used for integrations where stream-chat is used as a server-side service * interacting with Stream's REST API, not depending on any state and purely serving as a wrapper * around HTTP requests. Using this property on either the client side or a backend implementation * that also relies on WS events will break these functionalities, so please use carefully. */ disableCache?: boolean; enableInsights?: boolean; /** experimental feature, please contact support if you want this feature enabled for you */ enableWSFallback?: boolean; logger?: Logger; /** * Custom notification manager service to use for the client. * If not provided, a default notification manager will be created. * Notifications are used to communicate events like errors, warnings, info, etc. Other services can publish notifications or subscribe to the NotificationManager state changes. */ notifications?: NotificationManager; /** * When true, user will be persisted on client. Otherwise if `connectUser` call fails, then you need to * call `connectUser` again to retry. * This is mainly useful for chat application working in offline mode, where you will need client.user to * persist even if connectUser call fails. */ persistUserOnConnectionFailure?: boolean; /** * When network is recovered, we re-query the active channels on client. But in single query, you can recover * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state. * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this. * * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client. * When false, user/consumer of this client will need to make sure all the channels present on UI by * manually calling queryChannels endpoint. */ recoverStateOnReconnect?: boolean; warmUp?: boolean; /** * Set the instance of StableWSConnection on chat client. Its purely for testing purpose and should * not be used in production apps. */ wsConnection?: StableWSConnection; /** * Sets a suffix to the wsUrl when it is being built in `wsConnection`. Is meant to be * used purely in testing suites and should not be used in production apps. */ wsUrlParams?: URLSearchParams; }; export type SyncOptions = { /** * This will behave as queryChannels option. */ watch?: boolean; /** * Return channels from request that user does not have access to in a separate * field in the response called 'inaccessible_cids' instead of * adding them as 'notification.removed_from_channel' events. */ with_inaccessible_cids?: boolean; }; export type UnBanUserOptions = { client_id?: string; connection_id?: string; id?: string; shadow?: boolean; target_user_id?: string; type?: string; }; export type UpdateCommandOptions = { description: string; args?: string; set?: CommandVariants; }; export type UserOptions = { include_deactivated_users?: boolean; limit?: number; offset?: number; presence?: boolean; }; /** * Event Types */ export type ConnectionChangeEvent = { type: EventTypes; online?: boolean; }; export type Event = CustomEventData & { type: EventTypes; ai_message?: string; ai_state?: AIState; channel?: ChannelResponse; channel_custom?: CustomChannelData; channel_id?: string; channel_member_count?: number; channel_type?: string; cid?: string; clear_history?: boolean; connection_id?: string; // event creation timestamp, format Date ISO string created_at?: string; deleted_for_me?: boolean; draft?: DraftResponse; // id of the message that was marked as unread - all the following messages are considered unread. (notification.mark_unread) first_unread_message_id?: string; hard_delete?: boolean; last_delivered_at?: string; last_delivered_message_id?: string; // creation date of a message with last_read_message_id, formatted as Date ISO string last_read_at?: string; last_read_message_id?: string; live_location?: SharedLocationResponse; mark_messages_deleted?: boolean; me?: OwnUserResponse; member?: ChannelMemberResponse; message?: MessageResponse; message_id?: string; mode?: string; online?: boolean; own_capabilities?: string[]; parent_id?: string; poll?: PollResponse; poll_vote?: PollVote | PollAnswer; queriedChannels?: { channels: ChannelAPIResponse[]; isLatestMessageSet?: boolean; }; offlineReactions?: ReactionResponse[]; reaction?: ReactionResponse; received_at?: string | Date; reminder?: ReminderResponse; shadow?: boolean; team?: string; thread?: ThreadResponse; // @deprecated number of all unread messages across all current user's unread channels, equals unread_count total_unread_count?: number; // number of all current user's channels with at least one unread message including the channel in this event unread_channels?: number; // number of all unread messages across all current user's unread channels unread_count?: number; // number of unread messages in the channel from this event (notification.mark_unread) unread_messages?: number; unread_thread_messages?: number; unread_threads?: number; user?: UserResponse; user_id?: string; watcher_count?: number; channel_last_message_at?: string; app?: Record<string, unknown>; // TODO: further specify type }; export type UserCustomEvent = CustomEventData & { type: string; }; export type EventHandler = (event: Event) => void; export type EventTypes = 'all' | keyof typeof EVENT_MAP; /** * Filter Types */ export type AscDesc = 1 | -1; export type MessageFlagsFiltersOptions = { channel_cid?: string; is_reviewed?: boolean; team?: string; user_id?: string; }; export type MessageFlagsFilters = QueryFilters< { channel_cid?: | RequireOnlyOne< Pick<QueryFilter<MessageFlagsFiltersOptions['channel_cid']>, '$eq' | '$in'> > | PrimitiveFilter<MessageFlagsFiltersOptions['channel_cid']>; } & { team?: | RequireOnlyOne< Pick<QueryFilter<MessageFlagsFiltersOptions['team']>, '$eq' | '$in'> > | PrimitiveFilter<MessageFlagsFiltersOptions['team']>; } & { user_id?: | RequireOnlyOne< Pick<QueryFilter<MessageFlagsFiltersOptions['user_id']>, '$eq' | '$in'> > | PrimitiveFilter<MessageFlagsFiltersOptions['user_id']>; } & { [Key in keyof Omit< MessageFlagsFiltersOptions, 'channel_cid' | 'user_id' | 'is_reviewed' >]: | RequireOnlyOne<QueryFilter<MessageFlagsFiltersOptions[Key]>> | PrimitiveFilter<MessageFlagsFiltersOptions[Key]>; } >; export type FlagsFiltersOptions = { channel_cid?: string; message_id?: string; message_user_id?: string; reporter_id?: string; team?: string; user_id?: string; }; export type FlagsFilters = QueryFilters< { user_id?: | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['user_id']>, '$eq' | '$in'>> | PrimitiveFilter<FlagsFiltersOptions['user_id']>; } & { message_id?: | RequireOnlyOne< Pick<QueryFilter<FlagsFiltersOptions['message_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagsFiltersOptions['message_id']>; } & { message_user_id?: | RequireOnlyOne< Pick<QueryFilter<FlagsFiltersOptions['message_user_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagsFiltersOptions['message_user_id']>; } & { channel_cid?: | RequireOnlyOne< Pick<QueryFilter<FlagsFiltersOptions['channel_cid']>, '$eq' | '$in'> > | PrimitiveFilter<FlagsFiltersOptions['channel_cid']>; } & { reporter_id?: | RequireOnlyOne< Pick<QueryFilter<FlagsFiltersOptions['reporter_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagsFiltersOptions['reporter_id']>; } & { team?: | RequireOnlyOne<Pick<QueryFilter<FlagsFiltersOptions['team']>, '$eq' | '$in'>> | PrimitiveFilter<FlagsFiltersOptions['team']>; } >; export type FlagReportsFiltersOptions = { channel_cid?: string; is_reviewed?: boolean; message_id?: string; message_user_id?: string; report_id?: string; review_result?: string; reviewed_by?: string; team?: string; user_id?: string; }; export type FlagReportsFilters = QueryFilters< { report_id?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['report_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['report_id']>; } & { review_result?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['review_result']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['review_result']>; } & { reviewed_by?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['reviewed_by']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['reviewed_by']>; } & { user_id?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['user_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['user_id']>; } & { message_id?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['message_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['message_id']>; } & { message_user_id?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['message_user_id']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['message_user_id']>; } & { channel_cid?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['channel_cid']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['channel_cid']>; } & { team?: | RequireOnlyOne< Pick<QueryFilter<FlagReportsFiltersOptions['team']>, '$eq' | '$in'> > | PrimitiveFilter<FlagReportsFiltersOptions['team']>; } & { [Key in keyof Omit< FlagReportsFiltersOptions, 'report_id' | 'user_id' | 'message_id' | 'review_result' | 'reviewed_by' >]: | RequireOnlyOne<QueryFilter<FlagReportsFiltersOptions[Key]>> | PrimitiveFilter<FlagReportsFiltersOptions[Key]>; } >; export type BannedUsersFilterOptions = { banned_by_id?: string; channel_cid?: string; created_at?: string; reason?: string; user_id?: string; }; export type BannedUsersFilters = QueryFilters< { channel_cid?: | RequireOnlyOne< Pick<QueryFilter<BannedUsersFilterOptions['channel_cid']>, '$eq' | '$in'> > | PrimitiveFilter<BannedUsersFilterOptions['channel_cid']>; } & { reason?: | RequireOnlyOne< { $autocomplete?: BannedUsersFilterOptions['reason']; } & QueryFilter<BannedUsersFilterOptions['reason']> > | PrimitiveFilter<BannedUsersFilterOptions['reason']>; } & { [Key in keyof Omit<BannedUsersFilterOptions, 'channel_cid' | 'reason'>]: | RequireOnlyOne<QueryFilter<BannedUsersFilterOptions[Key]>> | PrimitiveFilter<BannedUsersFilterOptions[Key]>; } >; export type ReactionFilters = QueryFilters< { user_id?: | RequireOnlyOne<Pick<QueryFilter<ReactionResponse['user_id']>, '$eq' | '$in'>> | PrimitiveFilter<ReactionResponse['user_id']>; } & { type?: | RequireOnlyOne<Pick<QueryFilter<ReactionResponse['type']>, '$eq'>> | PrimitiveFilter<ReactionResponse['type']>; } & { created_at?: | RequireOnlyOne< Pick< QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte' > > | PrimitiveFilter<PollResponse['created_at']>; } >; export type ChannelFilters = QueryFilters< ContainsOperator<Omit<CustomChannelData, 'name'>> & { archived?: boolean; 'member.user.name'?: | RequireOnlyOne<{ $autocomplete?: string; $eq?: string; }> | string; members?: | RequireOnlyOne<Pick<QueryFilter<string>, '$in'>> | RequireOnlyOne<Pick<QueryFilter<string[]>, '$eq'>> | PrimitiveFilter<string[]>; name?: | RequireOnlyOne< { $autocomplete?: string; } & QueryFilter<string> > | PrimitiveFilter<string>; pinned?: boolean; last_updated?: | RequireOnlyOne<Pick<QueryFilter<string>, '$eq' | '$gt' | '$gte' | '$lt' | '$lte'>> | PrimitiveFilter<string>; } & { [Key in keyof Omit<ChannelResponse, 'name' | 'members' | keyof CustomChannelData>]: | RequireOnlyOne<QueryFilter<ChannelResponse[Key]>> | PrimitiveFilter<ChannelResponse[Key]>; } >; export type DraftFilters = { channel_cid?: | RequireOnlyOne<Pick<QueryFilter<DraftResponse['channel_cid']>, '$in' | '$eq'>> | PrimitiveFilter<DraftResponse['channel_cid']>; created_at?: | RequireOnlyOne< Pick< QueryFilter<DraftResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte' > > | PrimitiveFilter<DraftResponse['created_at']>; parent_id?: | RequireOnlyOne< Pick<QueryFilter<DraftResponse['created_at']>, '$in' | '$eq' | '$exists'> > | PrimitiveFilter<DraftResponse['parent_id']>; }; export type QueryPollsParams = { filter?: QueryPollsFilters; options?: QueryPollsOptions; sort?: PollSort; }; export type QueryPollsOptions = Pager; export type VotesFiltersOptions = { is_answer?: boolean; option_id?: string; user_id?: string; }; export type QueryVotesOptions = Pager; export type QueryPollsFilters = QueryFilters< { id?: | RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>; } & { user_id?: | RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>> | PrimitiveFilter<VotesFiltersOptions['user_id']>; } & { is_closed?: | RequireOnlyOne<Pick<QueryFilter<PollResponse['is_closed']>, '$eq'>> | PrimitiveFilter<PollResponse['is_closed']>; } & { max_votes_allowed?: | RequireOnlyOne< Pick< QueryFilter<PollResponse['max_votes_allowed']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte' > > | PrimitiveFilter<PollResponse['max_votes_allowed']>; } & { allow_answers?: | RequireOnlyOne<Pick<QueryFilter<PollResponse['allow_answers']>, '$eq'>> | PrimitiveFilter<PollResponse['allow_answers']>; } & { allow_user_suggested_options?: | RequireOnlyOne< Pick<QueryFilter<PollResponse['allow_user_suggested_options']>, '$eq'> > | PrimitiveFilter<PollResponse['allow_user_suggested_options']>; } & { voting_visibility?: | RequireOnlyOne<Pick<QueryFilter<PollResponse['voting_visibility']>, '$eq'>> | PrimitiveFilter<PollResponse['voting_visibility']>; } & { created_at?: | RequireOnlyOne< Pick< QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte' > > | PrimitiveFilter<PollResponse['created_at']>; } & { created_by_id?: | RequireOnlyOne<