stream-chat 9.16.0 → 9.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -1446,6 +1446,8 @@ export type Event = CustomEventData & {
1446
1446
  ai_message?: string;
1447
1447
  ai_state?: AIState;
1448
1448
  channel?: ChannelResponse;
1449
+ channel_custom?: CustomChannelData;
1450
+ channel_member_count?: number;
1449
1451
  channel_id?: string;
1450
1452
  channel_type?: string;
1451
1453
  cid?: string;
@@ -2242,6 +2244,7 @@ export type AppSettings = {
2242
2244
  disable_permissions_checks?: boolean;
2243
2245
  enforce_unique_usernames?: 'no' | 'app' | 'team';
2244
2246
  event_hooks?: Array<EventHook> | null;
2247
+ explicit_event_hooks_deletion?: boolean;
2245
2248
  // all possible file mime types are https://www.iana.org/assignments/media-types/media-types.xhtml
2246
2249
  file_upload_config?: FileUploadConfig;
2247
2250
  firebase_config?: {
@@ -3784,6 +3787,171 @@ export type UpsertConfigResponse = {
3784
3787
  config: ModerationConfigResponse;
3785
3788
  };
3786
3789
 
3790
+ // Moderation Rule Builder Types
3791
+ export type ModerationRule = {
3792
+ id: string;
3793
+ name: string;
3794
+ description: string;
3795
+ config_keys: string[];
3796
+ team: string;
3797
+ rule: RuleBuilderRule;
3798
+ enabled: boolean;
3799
+ created_at: string;
3800
+ updated_at: string;
3801
+ };
3802
+
3803
+ export type ModerationRuleRequest = {
3804
+ name: string;
3805
+ description: string;
3806
+ config_keys: string[];
3807
+ team: string;
3808
+ rule: RuleBuilderRule;
3809
+ enabled: boolean;
3810
+ };
3811
+
3812
+ export type RuleBuilderRule = {
3813
+ id: string;
3814
+ rule_type: 'user' | 'content';
3815
+ conditions?: RuleBuilderCondition[];
3816
+ logic?: 'AND' | 'OR';
3817
+ groups?: RuleBuilderConditionGroup[];
3818
+ action: RuleBuilderAction;
3819
+ cooldown_period?: string;
3820
+ };
3821
+
3822
+ export type RuleBuilderCondition = {
3823
+ type: string;
3824
+ confidence?: number;
3825
+ text_rule_params?: TextRuleParameters;
3826
+ image_rule_params?: ImageRuleParameters;
3827
+ video_rule_params?: VideoRuleParameters;
3828
+ user_rule_params?: UserRuleParameters;
3829
+ content_count_rule_params?: ContentCountRuleParameters;
3830
+ text_content_params?: TextContentParameters;
3831
+ image_content_params?: ImageContentParameters;
3832
+ video_content_params?: VideoContentParameters;
3833
+ user_created_within_params?: UserCreatedWithinParameters;
3834
+ user_custom_property_params?: UserCustomPropertyParameters;
3835
+ };
3836
+
3837
+ export type RuleBuilderConditionGroup = {
3838
+ logic: 'AND' | 'OR';
3839
+ conditions: RuleBuilderCondition[];
3840
+ };
3841
+
3842
+ export type RuleBuilderAction = {
3843
+ type: string;
3844
+ ban_options?: BanOptions;
3845
+ flag_user_options?: FlagUserOptions;
3846
+ flag_content_options?: FlagContentOptions;
3847
+ remove_content_options?: RemoveContentOptions;
3848
+ shadow_content_options?: ShadowContentOptions;
3849
+ };
3850
+
3851
+ export type TextRuleParameters = {
3852
+ threshold: number;
3853
+ time_window: string;
3854
+ harm_labels?: string[];
3855
+ llm_harm_labels?: Record<string, string>;
3856
+ contains_url?: boolean;
3857
+ severity?: string;
3858
+ blocklist_match?: string[];
3859
+ };
3860
+
3861
+ export type ImageRuleParameters = {
3862
+ threshold: number;
3863
+ time_window: string;
3864
+ harm_labels: string[];
3865
+ };
3866
+
3867
+ export type VideoRuleParameters = {
3868
+ threshold: number;
3869
+ time_window: string;
3870
+ harm_labels: string[];
3871
+ };
3872
+
3873
+ export type UserRuleParameters = {
3874
+ max_age: string;
3875
+ };
3876
+
3877
+ export type ContentCountRuleParameters = {
3878
+ threshold: number;
3879
+ time_window: string;
3880
+ };
3881
+
3882
+ export type TextContentParameters = {
3883
+ harm_labels?: string[];
3884
+ llm_harm_labels?: Record<string, string>;
3885
+ contains_url?: boolean;
3886
+ severity?: string;
3887
+ blocklist_match?: string[];
3888
+ };
3889
+
3890
+ export type ImageContentParameters = {
3891
+ harm_labels: string[];
3892
+ };
3893
+
3894
+ export type VideoContentParameters = {
3895
+ harm_labels: string[];
3896
+ };
3897
+
3898
+ export type UserCreatedWithinParameters = {
3899
+ max_age: string;
3900
+ };
3901
+
3902
+ export type UserCustomPropertyParameters = {
3903
+ property_key: string;
3904
+ operator: string;
3905
+ expected_value: string;
3906
+ };
3907
+
3908
+ export type BanOptions = {
3909
+ duration: number;
3910
+ reason: string;
3911
+ shadow_ban: boolean;
3912
+ ip_ban: boolean;
3913
+ };
3914
+
3915
+ export type FlagUserOptions = {
3916
+ reason: string;
3917
+ };
3918
+
3919
+ export type FlagContentOptions = {
3920
+ reason: string;
3921
+ };
3922
+
3923
+ export type RemoveContentOptions = {
3924
+ reason: string;
3925
+ };
3926
+
3927
+ export type ShadowContentOptions = {
3928
+ reason: string;
3929
+ };
3930
+
3931
+ export type QueryModerationRulesFilters = QueryFilters<{
3932
+ name?: string;
3933
+ team?: string;
3934
+ enabled?: boolean;
3935
+ rule_type?: string;
3936
+ created_at?: PrimitiveFilter<string>;
3937
+ updated_at?: PrimitiveFilter<string>;
3938
+ }>;
3939
+
3940
+ export type QueryModerationRulesSort = Array<
3941
+ Sort<'name' | 'enabled' | 'team' | 'created_at' | 'updated_at'>
3942
+ >;
3943
+
3944
+ export type QueryModerationRulesResponse = {
3945
+ rules: ModerationRule[];
3946
+ default_llm_labels: Record<string, string>;
3947
+ next?: string;
3948
+ prev?: string;
3949
+ };
3950
+
3951
+ export type UpsertModerationRuleResponse = {
3952
+ rule: ModerationRule;
3953
+ };
3954
+
3787
3955
  export type ModerationFlagOptions = {
3788
3956
  custom?: Record<string, unknown>;
3789
3957
  moderation_payload?: ModerationPayload;
@@ -4204,6 +4372,7 @@ export type EventHook = {
4204
4372
  id?: string;
4205
4373
  hook_type?: HookType;
4206
4374
  enabled?: boolean;
4375
+ product?: Product | 'all'; // optional, default is 'all'
4207
4376
  event_types?: Array<string>;
4208
4377
  webhook_url?: string;
4209
4378
  sqs_queue_url?: string;
@@ -4225,6 +4394,7 @@ export type EventHook = {
4225
4394
  mode: 'CALLBACK_MODE_NONE' | 'CALLBACK_MODE_REST' | 'CALLBACK_MODE_TWIRP';
4226
4395
  };
4227
4396
 
4397
+ delete?: boolean;
4228
4398
  created_at?: string;
4229
4399
  updated_at?: string;
4230
4400
  };
package/src/utils.ts CHANGED
@@ -416,6 +416,81 @@ export const toUpdatedMessagePayload = (
416
416
  };
417
417
  };
418
418
 
419
+ export const toDeletedMessage = ({
420
+ message,
421
+ deletedAt,
422
+ hardDelete = false,
423
+ }: {
424
+ message: LocalMessage | LocalMessageBase;
425
+ deletedAt: LocalMessage['deleted_at'];
426
+ hardDelete: boolean;
427
+ }) => {
428
+ if (hardDelete) {
429
+ /**
430
+ * In case of hard delete, we need to strip down all text, html, attachments and all the custom properties on message
431
+ * The hard-deleted message is kept in the UI until the messages are re-queried
432
+ * FIXME: we are returning an object that does not match LocalMessage | LocalMessageBase
433
+ */
434
+ return {
435
+ attachments: [],
436
+ cid: message.cid,
437
+ created_at: message.created_at,
438
+ deleted_at: deletedAt,
439
+ id: message.id,
440
+ latest_reactions: [],
441
+ mentioned_users: [],
442
+ own_reactions: [],
443
+ parent_id: message.parent_id,
444
+ reply_count: message.reply_count,
445
+ status: message.status,
446
+ thread_participants: message.thread_participants,
447
+ type: 'deleted' as const,
448
+ updated_at: message.updated_at,
449
+ user: message.user,
450
+ };
451
+ } else {
452
+ return {
453
+ ...message,
454
+ attachments: [],
455
+ type: 'deleted',
456
+ deleted_at: deletedAt,
457
+ };
458
+ }
459
+ };
460
+
461
+ export const deleteUserMessages = ({
462
+ messages,
463
+ user,
464
+ hardDelete = false,
465
+ deletedAt,
466
+ }: {
467
+ messages: Array<LocalMessage>;
468
+ user: UserResponse;
469
+ hardDelete: boolean;
470
+ deletedAt: LocalMessage['deleted_at'];
471
+ }) => {
472
+ for (let i = 0; i < messages.length; i++) {
473
+ const message = messages[i];
474
+ if (message.user?.id === user.id) {
475
+ messages[i] =
476
+ message.type === 'deleted'
477
+ ? message
478
+ : (toDeletedMessage({ message, hardDelete, deletedAt }) as LocalMessage);
479
+ }
480
+
481
+ if (message.quoted_message?.user?.id === user.id) {
482
+ messages[i].quoted_message =
483
+ message.quoted_message.type === 'deleted'
484
+ ? message.quoted_message
485
+ : (toDeletedMessage({
486
+ message: messages[i].quoted_message as LocalMessageBase,
487
+ hardDelete,
488
+ deletedAt,
489
+ }) as LocalMessage);
490
+ }
491
+ }
492
+ };
493
+
419
494
  export const findIndexInSortedArray = <T, L>({
420
495
  needle,
421
496
  sortedArray,