stream-chat 9.50.2 → 10.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.browser.js +18869 -13986
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +18888 -13992
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +18866 -13983
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/ChannelPaginatorsOrchestrator.d.ts +130 -0
- package/dist/types/EventHandlerPipeline.d.ts +104 -0
- package/dist/types/api-client.d.ts +26 -0
- package/dist/types/campaign.d.ts +0 -44
- package/dist/types/channel.d.ts +436 -480
- package/dist/types/channel_batch_updater.d.ts +0 -93
- package/dist/types/channel_manager.d.ts +8 -10
- package/dist/types/channel_state.d.ts +53 -201
- package/dist/types/client.d.ts +440 -1910
- package/dist/types/client_state.d.ts +4 -4
- package/dist/types/configuration/InstanceConfigurationService.d.ts +26 -0
- package/dist/types/configuration/index.d.ts +1 -0
- package/dist/types/configuration/types.d.ts +53 -0
- package/dist/types/connection.d.ts +49 -41
- package/dist/types/connection_fallback.d.ts +6 -4
- package/dist/types/constants.d.ts +0 -4
- package/dist/types/custom_types.d.ts +2 -0
- package/dist/types/errors.d.ts +2 -2
- package/dist/types/gen/chat/ChannelApi.d.ts +45 -0
- package/dist/types/gen/chat/ChatApi.d.ts +334 -0
- package/dist/types/gen/model-decoders/decoders.d.ts +3 -0
- package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
- package/dist/types/gen/models/index.d.ts +8836 -0
- package/dist/types/gen/moderation/ModerationApi.d.ts +50 -0
- package/dist/types/gen-imports.d.ts +3 -0
- package/dist/types/index.d.ts +5 -5
- package/dist/types/insights.d.ts +7 -6
- package/dist/types/logger.d.ts +9 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +7 -4
- package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -2
- package/dist/types/messageComposer/attachmentManager.d.ts +8 -4
- package/dist/types/messageComposer/configuration/types.d.ts +11 -11
- package/dist/types/messageComposer/linkPreviewsManager.d.ts +25 -13
- package/dist/types/messageComposer/messageComposer.d.ts +10 -10
- package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +3 -3
- package/dist/types/messageComposer/middleware/pollComposer/types.d.ts +4 -7
- package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +3 -3
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +7 -7
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +218 -4
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +9 -4
- package/dist/types/messageComposer/pollComposer.d.ts +5 -4
- package/dist/types/messageComposer/textComposer.d.ts +8 -3
- package/dist/types/messageComposer/types.d.ts +6 -28
- package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +40 -25
- package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +53 -12
- package/dist/types/messageOperations/MessageOperationStatePolicy.d.ts +19 -0
- package/dist/types/messageOperations/MessageOperations.d.ts +17 -0
- package/dist/types/messageOperations/index.d.ts +3 -0
- package/dist/types/messageOperations/types.d.ts +49 -0
- package/dist/types/moderation.d.ts +21 -203
- package/dist/types/notifications/types.d.ts +8 -7
- package/dist/types/offline-support/offline_support_api.d.ts +110 -87
- package/dist/types/offline-support/types.d.ts +19 -23
- package/dist/types/offline-support/util.d.ts +4 -2
- package/dist/types/pagination/FilterBuilder.d.ts +1 -1
- package/dist/types/pagination/ItemIndex.d.ts +82 -0
- package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +9 -0
- package/dist/types/pagination/cursorDerivation/idAroundPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/cursorDerivation/index.d.ts +1 -0
- package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/filterCompiler.d.ts +7 -0
- package/dist/types/pagination/index.d.ts +1 -3
- package/dist/types/pagination/paginators/BasePaginator.d.ts +709 -0
- package/dist/types/pagination/paginators/ChannelPaginator.d.ts +58 -0
- package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +260 -0
- package/dist/types/pagination/paginators/MessagePaginator.d.ts +208 -0
- package/dist/types/pagination/paginators/PinnedMessagePaginator.d.ts +39 -0
- package/dist/types/pagination/paginators/ReminderPaginator.d.ts +19 -0
- package/dist/types/pagination/paginators/UserGroupPaginator.d.ts +24 -0
- package/dist/types/pagination/paginators/index.d.ts +7 -0
- package/dist/types/pagination/sortCompiler.d.ts +49 -0
- package/dist/types/pagination/types.normalization.d.ts +11 -0
- package/dist/types/pagination/utility.normalization.d.ts +18 -0
- package/dist/types/pagination/utility.queryChannel.d.ts +26 -0
- package/dist/types/pagination/utility.search.d.ts +13 -0
- package/dist/types/permissions.d.ts +1 -1
- package/dist/types/poll.d.ts +29 -32
- package/dist/types/poll_manager.d.ts +2 -2
- package/dist/types/reminders/Reminder.d.ts +2 -5
- package/dist/types/reminders/ReminderManager.d.ts +2 -9
- package/dist/types/search/MessageSearchSource.d.ts +4 -4
- package/dist/types/search/UserSearchSource.d.ts +1 -1
- package/dist/types/search/types.d.ts +3 -3
- package/dist/types/segment.d.ts +0 -34
- package/dist/types/signing.d.ts +105 -65
- package/dist/types/store.d.ts +1 -0
- package/dist/types/thread.d.ts +51 -34
- package/dist/types/thread_manager.d.ts +3 -3
- package/dist/types/token_manager.d.ts +15 -10
- package/dist/types/types.d.ts +196 -3384
- package/dist/types/utils/FixedSizeQueueCache.d.ts +12 -6
- package/dist/types/utils/WithSubscriptions.d.ts +2 -1
- package/dist/types/utils/concurrency.d.ts +4 -4
- package/dist/types/utils/mergeWith/mergeWith.d.ts +3 -3
- package/dist/types/utils/mergeWith/mergeWithCore.d.ts +8 -3
- package/dist/types/utils/retryable.d.ts +34 -0
- package/dist/types/utils.d.ts +104 -137
- package/package.json +7 -3
- package/src/ChannelPaginatorsOrchestrator.ts +545 -0
- package/src/CooldownTimer.ts +2 -2
- package/src/EventHandlerPipeline.ts +228 -0
- package/src/LiveLocationManager.ts +12 -11
- package/src/api-client.ts +275 -0
- package/src/campaign.ts +1 -77
- package/src/channel.ts +1262 -1277
- package/src/channel_batch_updater.ts +1 -211
- package/src/channel_manager.ts +92 -88
- package/src/channel_state.ts +144 -1013
- package/src/client.ts +888 -3944
- package/src/client_state.ts +4 -4
- package/src/configuration/InstanceConfigurationService.ts +73 -0
- package/src/configuration/index.ts +1 -0
- package/src/configuration/types.ts +81 -0
- package/src/connection.ts +145 -94
- package/src/connection_fallback.ts +29 -27
- package/src/constants.ts +1 -5
- package/src/custom_types.ts +4 -1
- package/src/errors.ts +2 -2
- package/src/gen/chat/ChannelApi.ts +275 -0
- package/src/gen/chat/ChatApi.ts +2554 -0
- package/src/gen/model-decoders/decoders.ts +2680 -0
- package/src/gen/model-decoders/event-decoder-mapping.ts +198 -0
- package/src/gen/models/index.ts +12673 -0
- package/src/gen/moderation/ModerationApi.ts +607 -0
- package/src/gen-imports.ts +3 -0
- package/src/index.ts +5 -10
- package/src/insights.ts +6 -5
- package/src/logger.ts +28 -0
- package/src/messageComposer/LocationComposer.ts +9 -5
- package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
- package/src/messageComposer/attachmentIdentity.ts +16 -9
- package/src/messageComposer/attachmentManager.ts +13 -8
- package/src/messageComposer/configuration/types.ts +11 -11
- package/src/messageComposer/linkPreviewsManager.ts +9 -10
- package/src/messageComposer/messageComposer.ts +57 -53
- package/src/messageComposer/middleware/messageComposer/attachments.ts +1 -2
- package/src/messageComposer/middleware/messageComposer/cleanData.ts +1 -1
- package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/messageComposerState.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +4 -3
- package/src/messageComposer/middleware/messageComposer/textComposer.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/types.ts +3 -4
- package/src/messageComposer/middleware/messageComposer/userDataInjection.ts +9 -5
- package/src/messageComposer/middleware/pollComposer/state.ts +0 -2
- package/src/messageComposer/middleware/pollComposer/types.ts +4 -7
- package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +10 -1
- package/src/messageComposer/middleware/textComposer/commandEffects.ts +4 -4
- package/src/messageComposer/middleware/textComposer/commandUtils.ts +3 -6
- package/src/messageComposer/middleware/textComposer/commands.ts +3 -3
- package/src/messageComposer/middleware/textComposer/mentionUtils.ts +1 -1
- package/src/messageComposer/middleware/textComposer/mentions.ts +31 -15
- package/src/messageComposer/middleware/textComposer/types.ts +9 -4
- package/src/messageComposer/pollComposer.ts +6 -8
- package/src/messageComposer/textComposer.ts +27 -2
- package/src/messageComposer/types.ts +6 -28
- package/src/messageDelivery/MessageDeliveryReporter.ts +101 -45
- package/src/messageDelivery/MessageReceiptsTracker.ts +294 -21
- package/src/messageOperations/MessageOperationStatePolicy.ts +77 -0
- package/src/messageOperations/MessageOperations.ts +212 -0
- package/src/messageOperations/index.ts +10 -0
- package/src/messageOperations/types.ts +64 -0
- package/src/moderation.ts +38 -431
- package/src/notifications/types.ts +8 -7
- package/src/offline-support/offline_support_api.ts +198 -132
- package/src/offline-support/offline_sync_manager.ts +17 -7
- package/src/offline-support/types.ts +23 -26
- package/src/offline-support/util.ts +5 -4
- package/src/pagination/FilterBuilder.ts +4 -1
- package/src/pagination/ItemIndex.ts +112 -0
- package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +73 -0
- package/src/pagination/cursorDerivation/idAroundPaginationFlags.ts +53 -0
- package/src/pagination/cursorDerivation/index.ts +1 -0
- package/src/pagination/cursorDerivation/linearPaginationFlags.ts +86 -0
- package/src/pagination/filterCompiler.ts +196 -0
- package/src/pagination/index.ts +1 -3
- package/src/pagination/paginators/BasePaginator.ts +2393 -0
- package/src/pagination/paginators/ChannelPaginator.ts +427 -0
- package/src/pagination/paginators/MessageIntervalPaginator.ts +1073 -0
- package/src/pagination/paginators/MessagePaginator.ts +496 -0
- package/src/pagination/paginators/PinnedMessagePaginator.ts +105 -0
- package/src/pagination/paginators/ReminderPaginator.ts +105 -0
- package/src/pagination/paginators/UserGroupPaginator.ts +125 -0
- package/src/pagination/paginators/index.ts +7 -0
- package/src/pagination/sortCompiler.ts +178 -0
- package/src/pagination/types.normalization.ts +14 -0
- package/src/pagination/utility.normalization.ts +106 -0
- package/src/pagination/utility.queryChannel.ts +84 -0
- package/src/pagination/utility.search.ts +80 -0
- package/src/permissions.ts +7 -8
- package/src/poll.ts +101 -110
- package/src/poll_manager.ts +14 -8
- package/src/reminders/Reminder.ts +2 -5
- package/src/reminders/ReminderManager.ts +19 -21
- package/src/search/BaseSearchSource.ts +0 -3
- package/src/search/ChannelMemberSearchSource.ts +7 -1
- package/src/search/ChannelSearchSource.ts +10 -3
- package/src/search/MessageSearchSource.ts +29 -30
- package/src/search/UserSearchSource.ts +12 -8
- package/src/search/types.ts +3 -4
- package/src/segment.ts +1 -95
- package/src/signing.ts +107 -67
- package/src/store.ts +2 -1
- package/src/thread.ts +439 -236
- package/src/thread_manager.ts +36 -15
- package/src/token_manager.ts +21 -10
- package/src/types.ts +375 -4524
- package/src/uploadManager.ts +8 -0
- package/src/utils/FixedSizeQueueCache.ts +12 -6
- package/src/utils/WithSubscriptions.ts +2 -1
- package/src/utils/concurrency.ts +4 -4
- package/src/utils/mergeWith/mergeWith.ts +3 -3
- package/src/utils/mergeWith/mergeWithCore.ts +140 -164
- package/src/utils/mergeWith/mergeWithDiff.ts +3 -3
- package/src/utils/retryable.ts +117 -0
- package/src/utils.ts +133 -524
- package/dist/types/events.d.ts +0 -72
- package/dist/types/pagination/BasePaginator.d.ts +0 -69
- package/dist/types/pagination/ReminderPaginator.d.ts +0 -16
- package/dist/types/pagination/UserGroupPaginator.d.ts +0 -21
- package/src/events.ts +0 -75
- package/src/pagination/BasePaginator.ts +0 -184
- package/src/pagination/ReminderPaginator.ts +0 -56
- package/src/pagination/UserGroupPaginator.ts +0 -93
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
DraftMessage,
|
|
5
5
|
LiveLocationPayload,
|
|
6
6
|
LocalMessage,
|
|
7
|
-
|
|
7
|
+
SharedLocation,
|
|
8
8
|
} from '../types';
|
|
9
9
|
|
|
10
10
|
export type Coords = { latitude: number; longitude: number };
|
|
@@ -14,10 +14,13 @@ export type LocationComposerOptions = {
|
|
|
14
14
|
message?: DraftMessage | LocalMessage;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export type StaticLocationPreview =
|
|
17
|
+
export type StaticLocationPreview = SharedLocation & {
|
|
18
|
+
message_id?: string;
|
|
19
|
+
};
|
|
18
20
|
|
|
19
21
|
export type LiveLocationPreview = Omit<LiveLocationPayload, 'end_at'> & {
|
|
20
22
|
durationMs?: number;
|
|
23
|
+
message_id?: string;
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
export type LocationComposerState = {
|
|
@@ -59,7 +62,7 @@ export class LocationComposer {
|
|
|
59
62
|
return this.state.getLatestValue().location;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
get validLocation():
|
|
65
|
+
get validLocation(): SharedLocation | null {
|
|
63
66
|
const { durationMs, ...location } = (this.location ?? {}) as LiveLocationPreview;
|
|
64
67
|
if (
|
|
65
68
|
!!location?.created_by_device_id &&
|
|
@@ -71,8 +74,9 @@ export class LocationComposer {
|
|
|
71
74
|
) {
|
|
72
75
|
return {
|
|
73
76
|
...location,
|
|
74
|
-
end_at:
|
|
75
|
-
|
|
77
|
+
end_at:
|
|
78
|
+
typeof durationMs === 'number' ? new Date(Date.now() + durationMs) : undefined,
|
|
79
|
+
};
|
|
76
80
|
}
|
|
77
81
|
return null;
|
|
78
82
|
}
|
|
@@ -34,6 +34,7 @@ const applyCommandActivationEffect: MessageComposerEffectHandler<
|
|
|
34
34
|
suggestions: undefined,
|
|
35
35
|
selection: { start: 0, end: 0 },
|
|
36
36
|
text: '',
|
|
37
|
+
typing: {},
|
|
37
38
|
});
|
|
38
39
|
const attachmentsToCancel = composer.attachmentManager.attachments;
|
|
39
40
|
composer.attachmentManager.initState();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Attachment,
|
|
1
|
+
import type { Attachment, SharedLocationResponseData } from '../types';
|
|
2
2
|
import type {
|
|
3
3
|
AudioAttachment,
|
|
4
4
|
FileAttachment,
|
|
@@ -33,8 +33,10 @@ export const isFileAttachment = (
|
|
|
33
33
|
): attachment is FileAttachment =>
|
|
34
34
|
attachment.type === 'file' ||
|
|
35
35
|
!!(
|
|
36
|
-
attachment.mime_type &&
|
|
37
|
-
supportedVideoFormat.indexOf(
|
|
36
|
+
(attachment as FileAttachment).custom?.mime_type &&
|
|
37
|
+
supportedVideoFormat.indexOf(
|
|
38
|
+
(attachment as FileAttachment).custom?.mime_type as string,
|
|
39
|
+
) === -1 &&
|
|
38
40
|
attachment.type !== 'video'
|
|
39
41
|
);
|
|
40
42
|
|
|
@@ -76,7 +78,12 @@ export const isVideoAttachment = (
|
|
|
76
78
|
supportedVideoFormat: string[] = [],
|
|
77
79
|
): attachment is VideoAttachment =>
|
|
78
80
|
attachment.type === 'video' ||
|
|
79
|
-
!!(
|
|
81
|
+
!!(
|
|
82
|
+
(attachment as VideoAttachment).custom?.mime_type &&
|
|
83
|
+
supportedVideoFormat.indexOf(
|
|
84
|
+
(attachment as VideoAttachment).custom?.mime_type as string,
|
|
85
|
+
) !== -1
|
|
86
|
+
);
|
|
80
87
|
|
|
81
88
|
export const isLocalVideoAttachment = (
|
|
82
89
|
attachment: Attachment | LocalAttachment,
|
|
@@ -92,12 +99,12 @@ export const isUploadedAttachment = (
|
|
|
92
99
|
isVideoAttachment(attachment) ||
|
|
93
100
|
isVoiceRecordingAttachment(attachment);
|
|
94
101
|
|
|
95
|
-
export const
|
|
102
|
+
export const isSharedLocationResponseData = (
|
|
96
103
|
location: unknown,
|
|
97
|
-
): location is
|
|
98
|
-
!!(location as
|
|
99
|
-
!!(location as
|
|
100
|
-
!!(location as
|
|
104
|
+
): location is SharedLocationResponseData =>
|
|
105
|
+
!!(location as SharedLocationResponseData).latitude &&
|
|
106
|
+
!!(location as SharedLocationResponseData).longitude &&
|
|
107
|
+
!!(location as SharedLocationResponseData).channel_cid;
|
|
101
108
|
|
|
102
109
|
export const isGiphyAttachment = (
|
|
103
110
|
attachment: Attachment,
|
|
@@ -129,14 +129,14 @@ export class AttachmentManager {
|
|
|
129
129
|
this.composer.updateConfig({ attachments: { acceptedFiles } });
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
/**
|
|
133
133
|
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
134
134
|
*/
|
|
135
135
|
get fileUploadFilter() {
|
|
136
136
|
return this.config.fileUploadFilter;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
/**
|
|
140
140
|
@deprecated attachments can be filtered using injecting pre-upload middleware
|
|
141
141
|
*/
|
|
142
142
|
set fileUploadFilter(fileUploadFilter: AttachmentManagerConfig['fileUploadFilter']) {
|
|
@@ -426,8 +426,10 @@ export class AttachmentManager {
|
|
|
426
426
|
});
|
|
427
427
|
|
|
428
428
|
const localAttachment: LocalUploadAttachment = {
|
|
429
|
-
|
|
430
|
-
|
|
429
|
+
custom: {
|
|
430
|
+
file_size: file.size,
|
|
431
|
+
mime_type: file.type,
|
|
432
|
+
},
|
|
431
433
|
localMetadata: {
|
|
432
434
|
file,
|
|
433
435
|
id: generateUUIDv4(),
|
|
@@ -456,8 +458,12 @@ export class AttachmentManager {
|
|
|
456
458
|
localAttachment.thumb_url = fileLike.thumb_url;
|
|
457
459
|
}
|
|
458
460
|
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
+
if (
|
|
462
|
+
isFileReference(fileLike) &&
|
|
463
|
+
fileLike.duration &&
|
|
464
|
+
localAttachment.type === 'voiceRecording'
|
|
465
|
+
) {
|
|
466
|
+
localAttachment.custom.duration = fileLike.duration;
|
|
461
467
|
}
|
|
462
468
|
|
|
463
469
|
return localAttachment;
|
|
@@ -559,8 +565,7 @@ export class AttachmentManager {
|
|
|
559
565
|
mimeType: fileLike.type,
|
|
560
566
|
});
|
|
561
567
|
|
|
562
|
-
|
|
563
|
-
const { duration, ...result } = await this.channel[
|
|
568
|
+
const { duration: _duration, ...result } = await this.channel[
|
|
564
569
|
isImageFile(fileLike) ? 'sendImage' : 'sendFile'
|
|
565
570
|
](file, undefined, undefined, undefined, axiosUploadConfig);
|
|
566
571
|
return result;
|
|
@@ -2,7 +2,7 @@ import type { LinkPreview } from '../linkPreviewsManager';
|
|
|
2
2
|
import type { FileUploadFilter } from '../attachmentManager';
|
|
3
3
|
import type { MessageComposer } from '../messageComposer';
|
|
4
4
|
import type { FileLike, FileReference } from '../types';
|
|
5
|
-
import type {
|
|
5
|
+
import type { Command, UserResponse } from '../../types';
|
|
6
6
|
|
|
7
7
|
export type MinimumUploadRequestResult = { file: string; thumb_url?: string } & Partial<
|
|
8
8
|
Record<string, unknown>
|
|
@@ -41,14 +41,14 @@ export type TextComposerConfig = {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
export type CommandSendability = {
|
|
44
|
-
command:
|
|
44
|
+
command: Command;
|
|
45
45
|
ready: boolean;
|
|
46
46
|
reason?: string & {};
|
|
47
47
|
metadata?: Record<string, unknown>;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export type CommandSendValidationContext = {
|
|
51
|
-
command:
|
|
51
|
+
command: Command;
|
|
52
52
|
composer: MessageComposer;
|
|
53
53
|
commandArgsText: string;
|
|
54
54
|
mentionedUsersInText: UserResponse[];
|
|
@@ -80,17 +80,17 @@ export type AttachmentManagerConfig = {
|
|
|
80
80
|
/** Function that allows to customize the upload request. */
|
|
81
81
|
doUploadRequest?: UploadRequestFn;
|
|
82
82
|
/**
|
|
83
|
-
* When true
|
|
84
|
-
* to `doUploadRequest` (built-in and custom). Set to false to disable
|
|
85
|
-
*
|
|
83
|
+
* When `true`, the attachment manager sets `localMetadata.uploadProgress` and passes
|
|
84
|
+
* `options.onProgress` to `doUploadRequest` (built-in and custom). Set to `false` to disable
|
|
85
|
+
* progress tracking (defaults to `true`).
|
|
86
86
|
*/
|
|
87
87
|
trackUploadProgress: boolean;
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
export type LinkPreviewsManagerConfig = {
|
|
91
|
-
/** Number of milliseconds to debounce firing the URL enrichment queries when typing
|
|
91
|
+
/** Number of milliseconds to debounce firing the URL enrichment queries when typing (defaults to `1500`). */
|
|
92
92
|
debounceURLEnrichmentMs: number;
|
|
93
|
-
/** Allows for toggling the URL enrichment and link previews in `MessageInput
|
|
93
|
+
/** Allows for toggling the URL enrichment and link previews in `MessageInput` (defaults to `false`). */
|
|
94
94
|
enabled: boolean;
|
|
95
95
|
/** Custom function to identify URLs in a string and request OG data */
|
|
96
96
|
findURLFn: (text: string) => string[];
|
|
@@ -100,11 +100,11 @@ export type LinkPreviewsManagerConfig = {
|
|
|
100
100
|
|
|
101
101
|
export type LocationComposerConfig = {
|
|
102
102
|
/**
|
|
103
|
-
* Allows for toggling the location addition.
|
|
104
|
-
*
|
|
103
|
+
* Allows for toggling the location addition (defaults to `true`). The feature also has to be
|
|
104
|
+
* enabled at the channel-level config via `shared_locations`.
|
|
105
105
|
*/
|
|
106
106
|
enabled: boolean;
|
|
107
|
-
/** Function that provides a stable
|
|
107
|
+
/** Function that provides a stable ID for the device from which the location is shared. */
|
|
108
108
|
getDeviceId: () => string;
|
|
109
109
|
};
|
|
110
110
|
|
|
@@ -18,13 +18,13 @@ export interface ILinkPreviewsManager {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export enum LinkPreviewStatus {
|
|
21
|
-
/** Link preview has been dismissed using
|
|
21
|
+
/** Link preview has been dismissed using */
|
|
22
22
|
DISMISSED = 'dismissed',
|
|
23
|
-
/** Link preview could not be loaded, the enrichment request has failed.
|
|
23
|
+
/** Link preview could not be loaded, the enrichment request has failed. */
|
|
24
24
|
FAILED = 'failed',
|
|
25
|
-
/** Link preview has been successfully loaded.
|
|
25
|
+
/** Link preview has been successfully loaded. */
|
|
26
26
|
LOADED = 'loaded',
|
|
27
|
-
/** The enrichment query is in progress for a given link.
|
|
27
|
+
/** The enrichment query is in progress for a given link. */
|
|
28
28
|
LOADING = 'loading',
|
|
29
29
|
/** The preview reference enrichment has not begun. Default status if not set. */
|
|
30
30
|
PENDING = 'pending',
|
|
@@ -238,10 +238,9 @@ export class LinkPreviewsManager implements ILinkPreviewsManager {
|
|
|
238
238
|
await Promise.all(
|
|
239
239
|
newLinkPreviews.map(async (linkPreview) => {
|
|
240
240
|
try {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
);
|
|
241
|
+
const { duration: _duration, ...ogAttachment } = await this.client.getOG({
|
|
242
|
+
url: linkPreview.og_scrape_url,
|
|
243
|
+
});
|
|
245
244
|
if (this.shouldDiscardEnrichQueries) return;
|
|
246
245
|
// due to typing and text changes, the URL may not be anymore in the store
|
|
247
246
|
if (this.previews.has(linkPreview.og_scrape_url)) {
|
|
@@ -302,6 +301,7 @@ export class LinkPreviewsManager implements ILinkPreviewsManager {
|
|
|
302
301
|
...finalPreview,
|
|
303
302
|
og_scrape_url: url,
|
|
304
303
|
status,
|
|
304
|
+
custom: {},
|
|
305
305
|
}),
|
|
306
306
|
});
|
|
307
307
|
};
|
|
@@ -330,8 +330,7 @@ export class LinkPreviewsManager implements ILinkPreviewsManager {
|
|
|
330
330
|
preview.status === LinkPreviewStatus.PENDING;
|
|
331
331
|
|
|
332
332
|
static getPreviewData = (preview: LinkPreview) => {
|
|
333
|
-
|
|
334
|
-
const { status, ...data } = preview;
|
|
333
|
+
const { status: _status, ...data } = preview;
|
|
335
334
|
return data;
|
|
336
335
|
};
|
|
337
336
|
}
|
|
@@ -13,21 +13,22 @@ import {
|
|
|
13
13
|
} from './middleware';
|
|
14
14
|
import type { Unsubscribe } from '../store';
|
|
15
15
|
import { StateStore } from '../store';
|
|
16
|
-
import { formatMessage, generateUUIDv4, isLocalMessage
|
|
16
|
+
import { formatMessage, generateUUIDv4, isLocalMessage } from '../utils';
|
|
17
17
|
import { mergeWith } from '../utils/mergeWith';
|
|
18
18
|
import { Channel } from '../channel';
|
|
19
19
|
import { Thread } from '../thread';
|
|
20
20
|
import type {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
Attachment,
|
|
22
|
+
ChannelStateResponseFields,
|
|
23
|
+
Command,
|
|
23
24
|
DraftMessage,
|
|
24
25
|
DraftResponse,
|
|
25
|
-
|
|
26
|
+
EventType,
|
|
26
27
|
LocalMessage,
|
|
27
|
-
LocalMessageBase,
|
|
28
28
|
MessageResponse,
|
|
29
|
-
|
|
29
|
+
UserResponse,
|
|
30
30
|
} from '../types';
|
|
31
|
+
import { chatLoggerSystem } from '../logger';
|
|
31
32
|
import { WithSubscriptions } from '../utils/WithSubscriptions';
|
|
32
33
|
import type { StreamChat } from '../client';
|
|
33
34
|
import type { CommandSendability, MessageComposerConfig } from './configuration/types';
|
|
@@ -83,13 +84,14 @@ export type MessageComposerSnapshot = {
|
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
export type LocalMessageWithLegacyThreadId = LocalMessage & { legacyThreadId?: string };
|
|
87
|
+
// todo: remove LocalMessageWithLegacyThreadId
|
|
86
88
|
export type CompositionContext = Channel | Thread | LocalMessageWithLegacyThreadId;
|
|
87
89
|
|
|
88
90
|
export type MessageComposerState = {
|
|
89
91
|
id: string;
|
|
90
92
|
draftId: string | null;
|
|
91
93
|
pollId: string | null;
|
|
92
|
-
quotedMessage:
|
|
94
|
+
quotedMessage: LocalMessage | null;
|
|
93
95
|
showReplyInChannel: boolean;
|
|
94
96
|
/**
|
|
95
97
|
* Baseline snapshot of the message being edited (if any).
|
|
@@ -161,14 +163,15 @@ const initState = (
|
|
|
161
163
|
draftId,
|
|
162
164
|
id,
|
|
163
165
|
pollId: message.poll_id ?? null,
|
|
164
|
-
quotedMessage: quotedMessage
|
|
165
|
-
? formatMessage(quotedMessage as MessageResponseBase)
|
|
166
|
-
: null,
|
|
166
|
+
quotedMessage: quotedMessage ? formatMessage(quotedMessage) : null,
|
|
167
167
|
showReplyInChannel: false,
|
|
168
168
|
editedMessage,
|
|
169
169
|
};
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
+
const logger = chatLoggerSystem.getLogger('message-composer');
|
|
173
|
+
const offlineDbLogger = chatLoggerSystem.getLogger('offline-db');
|
|
174
|
+
|
|
172
175
|
export class MessageComposer extends WithSubscriptions {
|
|
173
176
|
readonly channel: Channel;
|
|
174
177
|
readonly state: StateStore<MessageComposerState>;
|
|
@@ -385,7 +388,7 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
385
388
|
}
|
|
386
389
|
|
|
387
390
|
getCommandDisabledReason = (
|
|
388
|
-
command:
|
|
391
|
+
command: Command,
|
|
389
392
|
): CommandSuggestionDisabledReason | undefined => {
|
|
390
393
|
if (this.editedMessage) return 'editing';
|
|
391
394
|
|
|
@@ -399,11 +402,10 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
399
402
|
return undefined;
|
|
400
403
|
};
|
|
401
404
|
|
|
402
|
-
isCommandDisabled = (command:
|
|
403
|
-
!!this.getCommandDisabledReason(command);
|
|
405
|
+
isCommandDisabled = (command: Command) => !!this.getCommandDisabledReason(command);
|
|
404
406
|
|
|
405
407
|
validateCommandSendability = (
|
|
406
|
-
command:
|
|
408
|
+
command: Command,
|
|
407
409
|
text = this.textComposer.text,
|
|
408
410
|
): CommandSendability => {
|
|
409
411
|
const currentMentionedUsers = this.textComposer.mentionedUsers;
|
|
@@ -505,8 +507,8 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
505
507
|
this.state.next(initState(composition));
|
|
506
508
|
};
|
|
507
509
|
|
|
508
|
-
initStateFromChannelResponse = (channelApiResponse:
|
|
509
|
-
if (this.channel.cid !== channelApiResponse.channel
|
|
510
|
+
initStateFromChannelResponse = (channelApiResponse: ChannelStateResponseFields) => {
|
|
511
|
+
if (this.channel.cid !== channelApiResponse.channel?.cid) {
|
|
510
512
|
return;
|
|
511
513
|
}
|
|
512
514
|
if (channelApiResponse.draft) {
|
|
@@ -615,12 +617,12 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
615
617
|
|
|
616
618
|
private subscribeMessageUpdated = () => {
|
|
617
619
|
// todo: test the impact of 'reaction.new', 'reaction.deleted', 'reaction.updated'
|
|
618
|
-
const eventTypes
|
|
620
|
+
const eventTypes = [
|
|
619
621
|
'message.updated',
|
|
620
622
|
'reaction.new',
|
|
621
623
|
'reaction.deleted', // todo: do we need to subscribe to this especially when the whole state is overriden?
|
|
622
624
|
'reaction.updated', // todo: do we need to subscribe to this especially when the whole state is overriden?
|
|
623
|
-
];
|
|
625
|
+
] satisfies EventType[];
|
|
624
626
|
|
|
625
627
|
const unsubscribeFunctions = eventTypes.map(
|
|
626
628
|
(eventType) =>
|
|
@@ -640,15 +642,16 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
640
642
|
|
|
641
643
|
private subscribeMessageComposerSetupStateChange = () => {
|
|
642
644
|
let tearDown: (() => void) | null = null;
|
|
643
|
-
const unsubscribe =
|
|
644
|
-
(
|
|
645
|
-
setup
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
645
|
+
const unsubscribe =
|
|
646
|
+
this.client.instanceConfigurationService.MessageComposer.subscribeWithSelector(
|
|
647
|
+
({ setupFunction: setup }) => ({
|
|
648
|
+
setup,
|
|
649
|
+
}),
|
|
650
|
+
({ setup }) => {
|
|
651
|
+
tearDown?.();
|
|
652
|
+
tearDown = setup?.({ composer: this }) ?? null;
|
|
653
|
+
},
|
|
654
|
+
);
|
|
652
655
|
|
|
653
656
|
return () => {
|
|
654
657
|
tearDown?.();
|
|
@@ -864,20 +867,21 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
864
867
|
type: 'regular',
|
|
865
868
|
},
|
|
866
869
|
localMessage: {
|
|
867
|
-
attachments: [],
|
|
870
|
+
attachments: [] as Attachment[],
|
|
871
|
+
cid: this.channel.cid, // it is needed to match local paginator filters to be ingested into its state
|
|
868
872
|
created_at, // only assigned to localMessage as this is used for optimistic update
|
|
869
|
-
deleted_at:
|
|
873
|
+
deleted_at: undefined,
|
|
870
874
|
error: undefined,
|
|
871
875
|
id: this.id,
|
|
872
|
-
mentioned_users: [],
|
|
876
|
+
mentioned_users: [] as UserResponse[],
|
|
873
877
|
parent_id: this.threadId ?? undefined,
|
|
874
|
-
pinned_at: this.editedMessage?.pinned_at ||
|
|
875
|
-
reaction_groups:
|
|
878
|
+
pinned_at: this.editedMessage?.pinned_at || undefined,
|
|
879
|
+
reaction_groups: undefined,
|
|
876
880
|
status: this.editedMessage ? this.editedMessage.status : 'sending',
|
|
877
881
|
text,
|
|
878
882
|
type: 'regular',
|
|
879
883
|
updated_at: created_at,
|
|
880
|
-
},
|
|
884
|
+
} as LocalMessage,
|
|
881
885
|
sendOptions: {},
|
|
882
886
|
},
|
|
883
887
|
});
|
|
@@ -891,7 +895,12 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
891
895
|
const { state, status } = await this.draftCompositionMiddlewareExecutor.execute({
|
|
892
896
|
eventName: 'compose',
|
|
893
897
|
initialValue: {
|
|
894
|
-
draft: {
|
|
898
|
+
draft: {
|
|
899
|
+
id: this.id,
|
|
900
|
+
parent_id: this.threadId ?? undefined,
|
|
901
|
+
text: '',
|
|
902
|
+
custom: {},
|
|
903
|
+
},
|
|
895
904
|
},
|
|
896
905
|
});
|
|
897
906
|
if (status === 'discard') return;
|
|
@@ -911,23 +920,20 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
911
920
|
try {
|
|
912
921
|
const optimisticDraftResponse = {
|
|
913
922
|
channel_cid: this.channel.cid,
|
|
914
|
-
created_at: new Date()
|
|
923
|
+
created_at: new Date(),
|
|
915
924
|
message: draft as DraftMessage,
|
|
916
925
|
parent_id: draft.parent_id,
|
|
917
|
-
quoted_message: this.quotedMessage
|
|
918
|
-
? unformatMessage(this.quotedMessage)
|
|
919
|
-
: undefined,
|
|
926
|
+
quoted_message: this.quotedMessage ?? undefined,
|
|
920
927
|
};
|
|
921
928
|
await this.client.offlineDb.upsertDraft({ draft: optimisticDraftResponse });
|
|
922
929
|
} catch (error) {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
error,
|
|
926
|
-
});
|
|
930
|
+
offlineDbLogger
|
|
931
|
+
.withExtraTags('createDraft', this.channel.cid)
|
|
932
|
+
.error('Upserting the draft to the offline database failed.', { error });
|
|
927
933
|
}
|
|
928
934
|
}
|
|
929
935
|
this.logDraftUpdateTimestamp();
|
|
930
|
-
await this.channel.createDraft(draft);
|
|
936
|
+
await this.channel.createDraft({ message: draft });
|
|
931
937
|
};
|
|
932
938
|
|
|
933
939
|
deleteDraft = async () => {
|
|
@@ -941,10 +947,9 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
941
947
|
parent_id: parentId,
|
|
942
948
|
});
|
|
943
949
|
} catch (error) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
error,
|
|
947
|
-
});
|
|
950
|
+
offlineDbLogger
|
|
951
|
+
.withExtraTags('deleteDraft', this.channel.cid)
|
|
952
|
+
.error('Deleting the draft from the offline database failed.', { error });
|
|
948
953
|
}
|
|
949
954
|
}
|
|
950
955
|
this.logDraftUpdateTimestamp();
|
|
@@ -952,11 +957,11 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
952
957
|
};
|
|
953
958
|
|
|
954
959
|
getDraft = async () => {
|
|
955
|
-
if (this.editedMessage || !this.config.drafts.enabled || !this.client.
|
|
960
|
+
if (this.editedMessage || !this.config.drafts.enabled || !this.client.userId) return;
|
|
956
961
|
|
|
957
962
|
const draftFromOfflineDB = await this.client.offlineDb?.getDraft({
|
|
958
963
|
cid: this.channel.cid,
|
|
959
|
-
userId: this.client.
|
|
964
|
+
userId: this.client.userId,
|
|
960
965
|
parent_id: this.threadId ?? undefined,
|
|
961
966
|
});
|
|
962
967
|
|
|
@@ -983,10 +988,9 @@ export class MessageComposer extends WithSubscriptions {
|
|
|
983
988
|
|
|
984
989
|
this.initState({ composition: draft });
|
|
985
990
|
} catch (error) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
error,
|
|
989
|
-
});
|
|
991
|
+
logger
|
|
992
|
+
.withExtraTags('getDraft', this.channel.cid)
|
|
993
|
+
.error('Retrieving the draft from the server failed.', { error });
|
|
990
994
|
}
|
|
991
995
|
};
|
|
992
996
|
|
|
@@ -10,8 +10,7 @@ import type {
|
|
|
10
10
|
} from './types';
|
|
11
11
|
|
|
12
12
|
const localAttachmentToAttachment = (localAttachment: LocalAttachment) => {
|
|
13
|
-
|
|
14
|
-
const { localMetadata, ...attachment } = localAttachment;
|
|
13
|
+
const { localMetadata: _localMetadata, ...attachment } = localAttachment;
|
|
15
14
|
return attachment as Attachment;
|
|
16
15
|
};
|
|
17
16
|
|
|
@@ -39,7 +39,7 @@ export const createCompositionDataCleanupMiddleware = (
|
|
|
39
39
|
...editedMessagePayloadToBeSent,
|
|
40
40
|
...state.message,
|
|
41
41
|
...common,
|
|
42
|
-
},
|
|
42
|
+
} as typeof state.message,
|
|
43
43
|
sendOptions:
|
|
44
44
|
composer.editedMessage && state.sendOptions?.skip_enrich_url
|
|
45
45
|
? { skip_enrich_url: state.sendOptions?.skip_enrich_url }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { textIsEmpty } from '../../textComposer';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Command } from '../../../types';
|
|
3
3
|
import { CommandSearchSource } from '../textComposer/commands';
|
|
4
4
|
import {
|
|
5
5
|
getCommandByName,
|
|
@@ -20,7 +20,7 @@ const getDisabledRawCommand = (
|
|
|
20
20
|
composer: MessageComposer,
|
|
21
21
|
searchSource: CommandSearchSource,
|
|
22
22
|
text?: string,
|
|
23
|
-
):
|
|
23
|
+
): Command | undefined => {
|
|
24
24
|
const rawCommand = getCommandByName(searchSource, getRawCommandName(text));
|
|
25
25
|
if (rawCommand && composer.isCommandDisabled(rawCommand)) {
|
|
26
26
|
return rawCommand;
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
MessageDraftCompositionMiddleware,
|
|
6
6
|
} from './types';
|
|
7
7
|
import type { MessageComposer } from '../../messageComposer';
|
|
8
|
-
import type { LocalMessage
|
|
8
|
+
import type { LocalMessage } from '../../../types';
|
|
9
9
|
import type { MiddlewareHandlerParams } from '../../../middleware';
|
|
10
10
|
|
|
11
11
|
export const createMessageComposerStateCompositionMiddleware = (
|
|
@@ -37,7 +37,7 @@ export const createMessageComposerStateCompositionMiddleware = (
|
|
|
37
37
|
localMessage: {
|
|
38
38
|
...state.localMessage,
|
|
39
39
|
...payload,
|
|
40
|
-
quoted_message:
|
|
40
|
+
quoted_message: composer.quotedMessage ?? undefined,
|
|
41
41
|
},
|
|
42
42
|
message: {
|
|
43
43
|
...state.message,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MiddlewareHandlerParams } from '../../../middleware';
|
|
2
|
+
import type { SharedLocationResponseData as Gen_SharedLocationResponseData } from '../../../gen/models';
|
|
2
3
|
import type { MessageComposer } from '../../messageComposer';
|
|
3
4
|
import type {
|
|
4
5
|
MessageComposerMiddlewareState,
|
|
@@ -18,7 +19,7 @@ export const createSharedLocationCompositionMiddleware = (
|
|
|
18
19
|
const { locationComposer } = composer;
|
|
19
20
|
const location = locationComposer.validLocation;
|
|
20
21
|
if (!locationComposer || !location || !composer.client.user) return forward();
|
|
21
|
-
const timestamp = new Date()
|
|
22
|
+
const timestamp = new Date();
|
|
22
23
|
|
|
23
24
|
return next({
|
|
24
25
|
...state,
|
|
@@ -30,12 +31,12 @@ export const createSharedLocationCompositionMiddleware = (
|
|
|
30
31
|
created_at: timestamp,
|
|
31
32
|
updated_at: timestamp,
|
|
32
33
|
user_id: composer.client.user.id,
|
|
33
|
-
},
|
|
34
|
+
} as Gen_SharedLocationResponseData,
|
|
34
35
|
},
|
|
35
36
|
message: {
|
|
36
37
|
...state.message,
|
|
37
38
|
shared_location: location,
|
|
38
|
-
},
|
|
39
|
+
} as typeof state.message,
|
|
39
40
|
});
|
|
40
41
|
},
|
|
41
42
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MiddlewareHandlerParams } from '../../../middleware';
|
|
2
|
-
import type {
|
|
2
|
+
import type { LocalMessage, MessageRequest, UserResponse } from '../../../types';
|
|
3
3
|
import type { MessageComposer } from '../../messageComposer';
|
|
4
4
|
import { mentionEntityToUserResponse } from '../textComposer/mentionUtils';
|
|
5
5
|
import type { MentionEntity } from '../textComposer/types';
|
|
@@ -30,7 +30,7 @@ type BuildMentionCompositionMetadataParams = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
type DraftMentionPayload = Pick<
|
|
33
|
-
|
|
33
|
+
MessageRequest,
|
|
34
34
|
| 'mentioned_channel'
|
|
35
35
|
| 'mentioned_group_ids'
|
|
36
36
|
| 'mentioned_here'
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { Middleware, MiddlewareExecutionResult } from '../../../middleware';
|
|
2
2
|
import type {
|
|
3
|
-
DraftMessagePayload,
|
|
4
3
|
LocalMessage,
|
|
5
|
-
|
|
4
|
+
MessageRequest,
|
|
6
5
|
SendMessageOptions,
|
|
7
6
|
UpdatedMessage,
|
|
8
7
|
} from '../../../types';
|
|
9
8
|
import type { MessageComposer } from '../../messageComposer';
|
|
10
9
|
|
|
11
10
|
export type MessageComposerMiddlewareState = {
|
|
12
|
-
message:
|
|
11
|
+
message: MessageRequest | UpdatedMessage;
|
|
13
12
|
localMessage: LocalMessage;
|
|
14
13
|
sendOptions: SendMessageOptions;
|
|
15
14
|
};
|
|
@@ -22,7 +21,7 @@ export type MessageComposerMiddlewareExecutorOptions = {
|
|
|
22
21
|
};
|
|
23
22
|
|
|
24
23
|
export type MessageDraftComposerMiddlewareValueState = {
|
|
25
|
-
draft:
|
|
24
|
+
draft: MessageRequest;
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export type MessageDraftComposerMiddlewareExecutorOptions = {
|