stream-chat
Version:
JS SDK for the Stream Chat API
1,487 lines • 101 kB
TypeScript
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>;
export type UR = Record<string, unknown>;
export type UnknownType = UR;
export type Unpacked<T> = T extends (infer U)[] ? U : 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?: {
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;
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[];
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;
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;
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 {
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;
}>;
}
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 declare 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;
removeDisable?: boolean;
};
export type ChannelPushPreference = {
chatLevel?: ChatLevelPushPreference;
disabledUntil?: string;
removeDisable?: boolean;
};
export type UpsertPushPreferencesResponse = APIResponse & {
userChannelPreferences: Record<string, Record<string, ChannelPushPreference>>;
userPreferences: Record<string, PushPreference>;
};
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[];
mentioned_users?: UserResponse[];
message_text_updated_at?: string;
moderation?: ModerationResponse;
moderation_details?: ModerationDetailsResponse;
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;
};
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;
};
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;
};
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;
};
};
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?: DeleteMessagesOptions;
};
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;
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 = 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;
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;
};
export type UpdateChannelTypeResponse = {
automod: Automod;
automod_behavior: AutomodBehavior;
commands: CommandVariants[];
connect_events: boolean;
created_at: string;
custom_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;
};
export type GetChannelTypeResponse = {
automod: Automod;
automod_behavior: AutomodBehavior;
commands: Command[];
connect_events: boolean;
created_at: string;
custom_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;
};
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 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;
};
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 = {
created_at_after?: string;
created_at_after_or_equal?: string;
created_at_before?: string;
created_at_before_or_equal?: string;
limit?: number;
offset?: number;
user_id_gt?: string;
user_id_gte?: string;
user_id_lt?: string;
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_id?: string;
channel_type?: string;
cid?: string;
clear_history?: boolean;
connection_id?: string;
created_at?: string;
draft?: DraftResponse;
first_unread_message_id?: string;
hard_delete?: boolean;
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;
total_unread_count?: number;
unread_channels?: number;
unread_count?: number;
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>;
};
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;
} & {
[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<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['created_by_id']>;
} & {
updated_at?: RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>> | PrimitiveFilter<PollResponse['updated_at']>;
} & {
name?: RequireOnlyOne<Pick<QueryFilter<PollResponse['name']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['name']>;
}>;
export type QueryVotesFilters = QueryFilters<{
id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['id']>;
} & {
option_id?: RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['option_id']>, '$eq' | '$in'>> | PrimitiveFilter<VotesFiltersOptions['option_id']>;
} & {
is_answer?: RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['is_answer']>, '$eq'>> | PrimitiveFilter<VotesFiltersOptions['is_answer']>;
} & {
user_id?: RequireOnlyOne<Pick<QueryFilter<VotesFiltersOptions['user_id']>, '$eq' | '$in'>> | PrimitiveFilter<VotesFiltersOptions['user_id']>;
} & {
created_at?: RequireOnlyOne<Pick<QueryFilter<PollResponse['created_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>> | PrimitiveFilter<PollResponse['created_at']>;
} & {
created_by_id?: RequireOnlyOne<Pick<QueryFilter<PollResponse['created_by_id']>, '$eq' | '$in'>> | PrimitiveFilter<PollResponse['created_by_id']>;
} & {
updated_at?: RequireOnlyOne<Pick<QueryFilter<PollResponse['updated_at']>, '$eq' | '$gt' | '$lt' | '$gte' | '$lte'>> | PrimitiveFilter<PollResponse['updated_at']>;
}>;
export type ContainsOperator<CustomType = {}> = {
[Key in keyof CustomType]?: CustomType[Key] extends (infer ContainType)[] ? RequireOnlyOne<{
$contains?: ContainType extends object ? PrimitiveFilter<RequireAtLeastOne<ContainType>> : PrimitiveFilter<ContainType>;
} & QueryFilter<PrimitiveFilter<ContainType>[]>> | PrimitiveFilter<PrimitiveFilter<ContainType>[]> : RequireOnlyOne<QueryFilter<CustomType[Key]>> | PrimitiveFilter<CustomType[Key]>;
};
export type MessageFilters = QueryFilters<ContainsOperator<CustomMessageData> & {
'attachments.type'?: RequireOnlyOne<{
$eq: PrimitiveFilter<Attachment['type']>;
$in: PrimitiveFilter<Attachment['type']>[];
}> | PrimitiveFilter<Attachment['type']>;
'mentioned_users.id'?: RequireOnlyOne<{
$contains: PrimitiveFilter<UserResponse['id']>;
}>;
text?: RequireOnlyOne<{
$autocomplete?: MessageResponse['text'];
$q?: MessageResponse['text'];
} & QueryFilter<MessageResponse['text']>> | PrimitiveFilter<MessageResponse['text']>;
'user.id'?: RequireOnlyOne<{
$autocomplete?: UserResponse['id'];
} & QueryFilter<UserResponse['id']>> | PrimitiveFilter<UserResponse['id']>;
} & {
[Key in keyof Omit<MessageRespons