stream-chat 9.44.1 → 9.45.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/dist/cjs/index.browser.js +3546 -2681
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +3555 -2681
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +3546 -2681
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/channel_manager.d.ts +5 -2
- package/dist/types/channel_state.d.ts +1 -1
- package/dist/types/client.d.ts +112 -5
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +1 -1
- package/dist/types/messageComposer/configuration/commands.configuration.d.ts +6 -0
- package/dist/types/messageComposer/configuration/configuration.d.ts +1 -2
- package/dist/types/messageComposer/configuration/index.d.ts +4 -0
- package/dist/types/messageComposer/configuration/types.d.ts +21 -0
- package/dist/types/messageComposer/fileUtils.d.ts +1 -1
- package/dist/types/messageComposer/messageComposer.d.ts +6 -4
- package/dist/types/messageComposer/middleware/messageComposer/compositionValidation.d.ts +2 -1
- package/dist/types/messageComposer/middleware/messageComposer/textComposer.d.ts +1 -1
- package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +10 -1
- package/dist/types/messageComposer/middleware/textComposer/mentionUtils.d.ts +8 -0
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +77 -15
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +51 -2
- package/dist/types/messageComposer/pollComposer.d.ts +2 -2
- package/dist/types/messageComposer/textComposer.d.ts +17 -3
- package/dist/types/pagination/UserGroupPaginator.d.ts +21 -0
- package/dist/types/pagination/index.d.ts +1 -0
- package/dist/types/types.d.ts +132 -2
- package/dist/types/utils.d.ts +2 -0
- package/package.json +38 -31
- package/src/channel_manager.ts +88 -13
- package/src/client.ts +217 -12
- package/src/constants.ts +1 -0
- package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
- package/src/messageComposer/configuration/commands.configuration.ts +55 -0
- package/src/messageComposer/configuration/configuration.ts +3 -1
- package/src/messageComposer/configuration/index.ts +4 -0
- package/src/messageComposer/configuration/types.ts +27 -0
- package/src/messageComposer/messageComposer.ts +73 -22
- package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +23 -15
- package/src/messageComposer/middleware/messageComposer/textComposer.ts +151 -31
- package/src/messageComposer/middleware/textComposer/commandUtils.ts +68 -1
- package/src/messageComposer/middleware/textComposer/commands.ts +6 -2
- package/src/messageComposer/middleware/textComposer/mentionUtils.ts +33 -0
- package/src/messageComposer/middleware/textComposer/mentions.ts +596 -66
- package/src/messageComposer/middleware/textComposer/types.ts +70 -2
- package/src/messageComposer/textComposer.ts +154 -10
- package/src/pagination/UserGroupPaginator.ts +93 -0
- package/src/pagination/index.ts +1 -0
- package/src/permissions.ts +1 -0
- package/src/types.ts +161 -2
- package/src/utils.ts +1 -0
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { textIsEmpty } from '../../textComposer';
|
|
2
2
|
import type { CommandResponse } from '../../../types';
|
|
3
3
|
import { CommandSearchSource } from '../textComposer/commands';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getCommandByName,
|
|
6
|
+
getRawCommandName,
|
|
7
|
+
notifyCommandDisabled,
|
|
8
|
+
notifyCommandNotReady,
|
|
9
|
+
} from '../textComposer/commandUtils';
|
|
5
10
|
import type {
|
|
6
11
|
MessageComposerMiddlewareState,
|
|
7
12
|
MessageCompositionMiddleware,
|
|
@@ -11,18 +16,6 @@ import type {
|
|
|
11
16
|
import type { MessageComposer } from '../../messageComposer';
|
|
12
17
|
import type { MiddlewareHandlerParams } from '../../../middleware';
|
|
13
18
|
|
|
14
|
-
const getCommandByName = (
|
|
15
|
-
searchSource: CommandSearchSource,
|
|
16
|
-
commandName?: string,
|
|
17
|
-
): CommandResponse | undefined => {
|
|
18
|
-
if (!commandName) return;
|
|
19
|
-
|
|
20
|
-
const normalizedCommandName = commandName.toLowerCase();
|
|
21
|
-
return searchSource
|
|
22
|
-
.query(normalizedCommandName)
|
|
23
|
-
.items.find((command) => command.name?.toLowerCase() === normalizedCommandName);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
19
|
const getDisabledRawCommand = (
|
|
27
20
|
composer: MessageComposer,
|
|
28
21
|
searchSource: CommandSearchSource,
|
|
@@ -36,8 +29,10 @@ const getDisabledRawCommand = (
|
|
|
36
29
|
|
|
37
30
|
export const createCompositionValidationMiddleware = (
|
|
38
31
|
composer: MessageComposer,
|
|
32
|
+
commandSearchSource?: CommandSearchSource,
|
|
39
33
|
): MessageCompositionMiddleware => {
|
|
40
|
-
const
|
|
34
|
+
const effectiveCommandSearchSource =
|
|
35
|
+
commandSearchSource ?? new CommandSearchSource(composer.channel);
|
|
41
36
|
|
|
42
37
|
return {
|
|
43
38
|
id: 'stream-io/message-composer-middleware/data-validation',
|
|
@@ -52,7 +47,7 @@ export const createCompositionValidationMiddleware = (
|
|
|
52
47
|
|
|
53
48
|
const disabledRawCommand = getDisabledRawCommand(
|
|
54
49
|
composer,
|
|
55
|
-
|
|
50
|
+
effectiveCommandSearchSource,
|
|
56
51
|
inputText,
|
|
57
52
|
);
|
|
58
53
|
if (disabledRawCommand) {
|
|
@@ -60,6 +55,19 @@ export const createCompositionValidationMiddleware = (
|
|
|
60
55
|
return await discard();
|
|
61
56
|
}
|
|
62
57
|
|
|
58
|
+
const currentCommand =
|
|
59
|
+
composer.textComposer.command ??
|
|
60
|
+
getCommandByName(effectiveCommandSearchSource, getRawCommandName(inputText));
|
|
61
|
+
if (
|
|
62
|
+
currentCommand &&
|
|
63
|
+
notifyCommandNotReady({
|
|
64
|
+
composer,
|
|
65
|
+
sendability: composer.validateCommandSendability(currentCommand, inputText),
|
|
66
|
+
})
|
|
67
|
+
) {
|
|
68
|
+
return await discard();
|
|
69
|
+
}
|
|
70
|
+
|
|
63
71
|
const hasExceededMaxLength =
|
|
64
72
|
typeof maxLengthOnSend === 'number' && inputText.length > maxLengthOnSend;
|
|
65
73
|
|
|
@@ -1,11 +1,114 @@
|
|
|
1
|
+
import type { MiddlewareHandlerParams } from '../../../middleware';
|
|
2
|
+
import type { DraftMessage, LocalMessage, UserResponse } from '../../../types';
|
|
3
|
+
import type { MessageComposer } from '../../messageComposer';
|
|
4
|
+
import { mentionEntityToUserResponse } from '../textComposer/mentionUtils';
|
|
5
|
+
import type { MentionEntity } from '../textComposer/types';
|
|
1
6
|
import type {
|
|
2
7
|
MessageComposerMiddlewareState,
|
|
3
8
|
MessageCompositionMiddleware,
|
|
4
9
|
MessageDraftComposerMiddlewareValueState,
|
|
5
10
|
MessageDraftCompositionMiddleware,
|
|
6
11
|
} from './types';
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
|
|
13
|
+
type MentionPayloadBase = Pick<
|
|
14
|
+
LocalMessage,
|
|
15
|
+
'mentioned_channel' | 'mentioned_group_ids' | 'mentioned_here' | 'mentioned_roles'
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
type MentionCompositionMetadata = Omit<
|
|
19
|
+
Required<MentionPayloadBase>,
|
|
20
|
+
'mentioned_channel' | 'mentioned_here'
|
|
21
|
+
> & {
|
|
22
|
+
mentioned_channel: boolean;
|
|
23
|
+
mentioned_here: boolean;
|
|
24
|
+
mentioned_users: UserResponse[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type BuildMentionCompositionMetadataParams = {
|
|
28
|
+
mentions: MentionEntity[];
|
|
29
|
+
text: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type DraftMentionPayload = Pick<
|
|
33
|
+
DraftMessage,
|
|
34
|
+
| 'mentioned_channel'
|
|
35
|
+
| 'mentioned_group_ids'
|
|
36
|
+
| 'mentioned_here'
|
|
37
|
+
| 'mentioned_roles'
|
|
38
|
+
| 'mentioned_users'
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
const textIncludesMentionToken = (text: string, token: string) =>
|
|
42
|
+
text.includes(`@${token}`);
|
|
43
|
+
const isDefined = <TValue>(value: TValue | undefined): value is TValue =>
|
|
44
|
+
value !== undefined;
|
|
45
|
+
|
|
46
|
+
const getMentionEntityTextCandidates = (entity: MentionEntity) => {
|
|
47
|
+
if (entity.mentionType === 'channel') return ['channel'];
|
|
48
|
+
if (entity.mentionType === 'here') return ['here'];
|
|
49
|
+
if (entity.mentionType === 'user') return [entity.id, entity.name].filter(isDefined);
|
|
50
|
+
if (entity.mentionType === 'role') return [entity.name, entity.id].filter(isDefined);
|
|
51
|
+
if (entity.mentionType === 'user_group') {
|
|
52
|
+
return entity.name ? [entity.name, entity.id].filter(isDefined) : [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return [];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const isMentionEntityPresentInText = (entity: MentionEntity, text: string) => {
|
|
59
|
+
const textCandidates = getMentionEntityTextCandidates(entity);
|
|
60
|
+
if (!textCandidates.length) return true;
|
|
61
|
+
|
|
62
|
+
return textCandidates.some((candidate) => textIncludesMentionToken(text, candidate));
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const dedupeBy = <TItem, TKey extends string>(
|
|
66
|
+
items: TItem[],
|
|
67
|
+
getKey: (item: TItem) => TKey,
|
|
68
|
+
) => {
|
|
69
|
+
const uniqueItems = new Map<TKey, TItem>();
|
|
70
|
+
|
|
71
|
+
items.forEach((item) => {
|
|
72
|
+
uniqueItems.set(getKey(item), item);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return [...uniqueItems.values()];
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const buildMentionCompositionMetadata = ({
|
|
79
|
+
mentions,
|
|
80
|
+
text,
|
|
81
|
+
}: BuildMentionCompositionMetadataParams): MentionCompositionMetadata => {
|
|
82
|
+
const presentMentions = dedupeBy(
|
|
83
|
+
mentions.filter((entity) => isMentionEntityPresentInText(entity, text)),
|
|
84
|
+
(entity) => `${entity.mentionType}:${entity.id}`,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return presentMentions.reduce<MentionCompositionMetadata>(
|
|
88
|
+
(acc, entity) => {
|
|
89
|
+
if (entity.mentionType === 'user') {
|
|
90
|
+
acc.mentioned_users.push(mentionEntityToUserResponse(entity));
|
|
91
|
+
} else if (entity.mentionType === 'channel') {
|
|
92
|
+
acc.mentioned_channel = true;
|
|
93
|
+
} else if (entity.mentionType === 'here') {
|
|
94
|
+
acc.mentioned_here = true;
|
|
95
|
+
} else if (entity.mentionType === 'role') {
|
|
96
|
+
acc.mentioned_roles.push(entity.id);
|
|
97
|
+
} else if (entity.mentionType === 'user_group') {
|
|
98
|
+
acc.mentioned_group_ids.push(entity.id);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return acc;
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
mentioned_channel: false,
|
|
105
|
+
mentioned_group_ids: [],
|
|
106
|
+
mentioned_here: false,
|
|
107
|
+
mentioned_roles: [],
|
|
108
|
+
mentioned_users: [],
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
};
|
|
9
112
|
|
|
10
113
|
export const createTextComposerCompositionMiddleware = (
|
|
11
114
|
composer: MessageComposer,
|
|
@@ -18,30 +121,44 @@ export const createTextComposerCompositionMiddleware = (
|
|
|
18
121
|
forward,
|
|
19
122
|
}: MiddlewareHandlerParams<MessageComposerMiddlewareState>) => {
|
|
20
123
|
if (!composer.textComposer) return forward();
|
|
21
|
-
const {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
124
|
+
const { mentions, text } = composer.textComposer;
|
|
125
|
+
const {
|
|
126
|
+
mentioned_channel,
|
|
127
|
+
mentioned_group_ids,
|
|
128
|
+
mentioned_here,
|
|
129
|
+
mentioned_roles,
|
|
130
|
+
mentioned_users,
|
|
131
|
+
} = buildMentionCompositionMetadata({ mentions, text });
|
|
132
|
+
|
|
133
|
+
// prevent introducing text and mention metadata into the payload sent to the server
|
|
134
|
+
if (
|
|
135
|
+
!text &&
|
|
136
|
+
!mentioned_channel &&
|
|
137
|
+
!mentioned_here &&
|
|
138
|
+
mentioned_group_ids.length === 0 &&
|
|
139
|
+
mentioned_roles.length === 0 &&
|
|
140
|
+
mentioned_users.length === 0
|
|
141
|
+
) {
|
|
142
|
+
return forward();
|
|
143
|
+
}
|
|
35
144
|
|
|
36
145
|
return next({
|
|
37
146
|
...state,
|
|
38
147
|
localMessage: {
|
|
39
148
|
...state.localMessage,
|
|
149
|
+
mentioned_channel,
|
|
150
|
+
mentioned_group_ids,
|
|
151
|
+
mentioned_here,
|
|
152
|
+
mentioned_roles,
|
|
40
153
|
mentioned_users,
|
|
41
154
|
text,
|
|
42
155
|
},
|
|
43
156
|
message: {
|
|
44
157
|
...state.message,
|
|
158
|
+
mentioned_channel,
|
|
159
|
+
mentioned_group_ids,
|
|
160
|
+
mentioned_here,
|
|
161
|
+
mentioned_roles,
|
|
45
162
|
mentioned_users: mentioned_users.map((u) => u.id),
|
|
46
163
|
text,
|
|
47
164
|
},
|
|
@@ -62,31 +179,34 @@ export const createDraftTextComposerCompositionMiddleware = (
|
|
|
62
179
|
}: MiddlewareHandlerParams<MessageDraftComposerMiddlewareValueState>) => {
|
|
63
180
|
if (!composer.textComposer) return forward();
|
|
64
181
|
const { maxLengthOnSend } = composer.config.text ?? {};
|
|
65
|
-
const {
|
|
66
|
-
// Instead of checking if a user is still mentioned every time the text changes,
|
|
67
|
-
// just filter out non-mentioned users before submit, which is cheaper
|
|
68
|
-
// and allows users to easily undo any accidental deletion
|
|
69
|
-
const mentioned_users = mentionedUsers.length
|
|
70
|
-
? Array.from(
|
|
71
|
-
new Set(
|
|
72
|
-
mentionedUsers.filter(
|
|
73
|
-
({ id, name }) =>
|
|
74
|
-
inputText.includes(`@${id}`) || inputText.includes(`@${name}`),
|
|
75
|
-
),
|
|
76
|
-
),
|
|
77
|
-
)
|
|
78
|
-
: undefined;
|
|
182
|
+
const { mentions, text: inputText } = composer.textComposer;
|
|
79
183
|
|
|
80
184
|
const text =
|
|
81
185
|
typeof maxLengthOnSend === 'number' && inputText.length > maxLengthOnSend
|
|
82
186
|
? inputText.slice(0, maxLengthOnSend)
|
|
83
187
|
: inputText;
|
|
188
|
+
const {
|
|
189
|
+
mentioned_channel,
|
|
190
|
+
mentioned_group_ids,
|
|
191
|
+
mentioned_here,
|
|
192
|
+
mentioned_roles,
|
|
193
|
+
mentioned_users,
|
|
194
|
+
} = buildMentionCompositionMetadata({ mentions, text });
|
|
195
|
+
const draftMentionPayload: DraftMentionPayload = {
|
|
196
|
+
...(mentioned_channel ? { mentioned_channel: true } : {}),
|
|
197
|
+
...(mentioned_group_ids.length ? { mentioned_group_ids } : {}),
|
|
198
|
+
...(mentioned_here ? { mentioned_here: true } : {}),
|
|
199
|
+
...(mentioned_roles.length ? { mentioned_roles } : {}),
|
|
200
|
+
...(mentioned_users.length
|
|
201
|
+
? { mentioned_users: mentioned_users.map((u) => u.id) }
|
|
202
|
+
: {}),
|
|
203
|
+
};
|
|
84
204
|
|
|
85
205
|
return next({
|
|
86
206
|
...state,
|
|
87
207
|
draft: {
|
|
88
208
|
...state.draft,
|
|
89
|
-
|
|
209
|
+
...draftMentionPayload,
|
|
90
210
|
text,
|
|
91
211
|
},
|
|
92
212
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { MessageComposer } from '../../messageComposer';
|
|
2
|
-
import type { CommandResponse } from '../../../types';
|
|
2
|
+
import type { CommandResponse, UserResponse } from '../../../types';
|
|
3
|
+
import type { CommandSendability } from '../../configuration';
|
|
4
|
+
import type { CommandSearchSource } from './commands';
|
|
3
5
|
|
|
4
6
|
export function escapeCommandRegExp(text: string) {
|
|
5
7
|
return text.replace(/[-[\]{}()*+?.,/\\^$|#]/g, '\\$&');
|
|
@@ -19,6 +21,43 @@ export const getCompleteCommandInString = (text: string) => {
|
|
|
19
21
|
export const stripCommandFromText = (text: string, commandName: string) =>
|
|
20
22
|
text.replace(new RegExp(`^${escapeCommandRegExp(`/${commandName}`)}\\s*`), '');
|
|
21
23
|
|
|
24
|
+
export const stripMentionTokens = (
|
|
25
|
+
text: string,
|
|
26
|
+
mentionedUsersInText: UserResponse[],
|
|
27
|
+
trigger = '@',
|
|
28
|
+
) =>
|
|
29
|
+
mentionedUsersInText.reduce((value, user) => {
|
|
30
|
+
let next = value.replace(`${trigger}${user.id}`, '');
|
|
31
|
+
|
|
32
|
+
if (user.name) {
|
|
33
|
+
next = next.replace(`${trigger}${user.name}`, '');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return next.trim();
|
|
37
|
+
}, text.trim());
|
|
38
|
+
|
|
39
|
+
export const getMentionedUsersInText = (text: string, mentionedUsers: UserResponse[]) =>
|
|
40
|
+
Array.from(
|
|
41
|
+
new Set(
|
|
42
|
+
mentionedUsers.filter(
|
|
43
|
+
({ id, name }) =>
|
|
44
|
+
text.includes(`@${id}`) || (!!name && text.includes(`@${name}`)),
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const getCommandByName = (
|
|
50
|
+
searchSource: CommandSearchSource,
|
|
51
|
+
commandName?: string,
|
|
52
|
+
): CommandResponse | undefined => {
|
|
53
|
+
if (!commandName) return;
|
|
54
|
+
|
|
55
|
+
const normalizedCommandName = commandName.toLowerCase();
|
|
56
|
+
return searchSource
|
|
57
|
+
.query(normalizedCommandName)
|
|
58
|
+
.items.find((command) => command.name?.toLowerCase() === normalizedCommandName);
|
|
59
|
+
};
|
|
60
|
+
|
|
22
61
|
export const notifyCommandDisabled = (
|
|
23
62
|
composer: MessageComposer,
|
|
24
63
|
command: CommandResponse,
|
|
@@ -46,3 +85,31 @@ export const notifyCommandDisabled = (
|
|
|
46
85
|
|
|
47
86
|
return true;
|
|
48
87
|
};
|
|
88
|
+
|
|
89
|
+
export const notifyCommandNotReady = ({
|
|
90
|
+
composer,
|
|
91
|
+
sendability,
|
|
92
|
+
}: {
|
|
93
|
+
composer: MessageComposer;
|
|
94
|
+
sendability: CommandSendability;
|
|
95
|
+
}) => {
|
|
96
|
+
if (sendability.ready) return;
|
|
97
|
+
|
|
98
|
+
composer.client.notifications.addWarning({
|
|
99
|
+
message: 'Command not ready to be sent',
|
|
100
|
+
origin: {
|
|
101
|
+
emitter: 'MessageComposer',
|
|
102
|
+
context: { command: sendability.command, composer },
|
|
103
|
+
},
|
|
104
|
+
options: {
|
|
105
|
+
type: 'validation:command:not-ready',
|
|
106
|
+
metadata: {
|
|
107
|
+
command: sendability.command.name,
|
|
108
|
+
...(sendability.reason ? { reason: sendability.reason } : {}),
|
|
109
|
+
...(sendability.metadata ?? {}),
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
@@ -6,7 +6,11 @@ import type { CommandResponse } from '../../../types';
|
|
|
6
6
|
import { mergeWith } from '../../../utils/mergeWith';
|
|
7
7
|
import type { MessageComposer } from '../../messageComposer';
|
|
8
8
|
import type { CommandSuggestion, TextComposerMiddlewareOptions } from './types';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getCommandByName,
|
|
11
|
+
getCompleteCommandInString,
|
|
12
|
+
notifyCommandDisabled,
|
|
13
|
+
} from './commandUtils';
|
|
10
14
|
import { getTriggerCharWithToken, insertItemWithTrigger } from './textMiddlewareUtils';
|
|
11
15
|
import type { TextComposerMiddlewareExecutorState } from './TextComposerMiddlewareExecutor';
|
|
12
16
|
|
|
@@ -124,7 +128,7 @@ export const createCommandsMiddleware = (
|
|
|
124
128
|
const finalText = state.text.slice(0, state.selection.end);
|
|
125
129
|
const commandName = getCompleteCommandInString(finalText);
|
|
126
130
|
if (commandName) {
|
|
127
|
-
const command = searchSource
|
|
131
|
+
const command = getCommandByName(searchSource, commandName);
|
|
128
132
|
const composer = options?.composer;
|
|
129
133
|
if (command && !composer?.isCommandDisabled(command)) {
|
|
130
134
|
return next({
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { UserResponse } from '../../../types';
|
|
2
|
+
import type { MentionEntity, UserMentionEntity, UserSuggestion } from './types';
|
|
3
|
+
|
|
4
|
+
export const isUserMentionEntity = (entity: MentionEntity): entity is UserMentionEntity =>
|
|
5
|
+
entity.mentionType === 'user';
|
|
6
|
+
|
|
7
|
+
export const userResponseToMentionEntity = (user: UserResponse): UserMentionEntity => ({
|
|
8
|
+
...user,
|
|
9
|
+
mentionType: 'user',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const userResponsesToMentionEntities = (users: UserResponse[]) =>
|
|
13
|
+
users.map(userResponseToMentionEntity);
|
|
14
|
+
|
|
15
|
+
export const mentionEntityToUserResponse = (entity: UserMentionEntity): UserResponse => {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
+
const { mentionType, ...user } = entity;
|
|
18
|
+
return user;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const userSuggestionToUserResponse = (
|
|
22
|
+
suggestion: UserSuggestion,
|
|
23
|
+
): UserResponse => {
|
|
24
|
+
const { mentionType, tokenizedDisplayName, ...userResponse } = suggestion;
|
|
25
|
+
void mentionType;
|
|
26
|
+
void tokenizedDisplayName;
|
|
27
|
+
return userResponse;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const userSuggestionToMentionEntity = (
|
|
31
|
+
suggestion: UserSuggestion,
|
|
32
|
+
): UserMentionEntity =>
|
|
33
|
+
userResponseToMentionEntity(userSuggestionToUserResponse(suggestion));
|