-
Notifications
You must be signed in to change notification settings - Fork 13.5k
refactor(chat): migrate chat.getThreadsList to typed REST endpoint #39655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
db76f3b
a70323a
f96897f
257ef25
d824760
74a4189
ae953d1
1321390
076ba11
8f51c3c
94f9c5a
dd0ecc9
ae055a8
f57fa3f
8aaca4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -275,6 +275,38 @@ const isChatPinMessageProps = ajv.compile<ChatPinMessage>(ChatPinMessageSchema); | |
|
|
||
| const isChatUnpinMessageProps = ajv.compile<ChatUnpinMessage>(ChatUnpinMessageSchema); | ||
|
|
||
| const isChatGetThreadsListResponse = ajv.compile<{ | ||
| threads: IMessage[]; | ||
| count: number; | ||
| offset: number; | ||
| total: number; | ||
| }>({ | ||
| type: 'object', | ||
| properties: { | ||
| threads: { | ||
| type: 'array', | ||
| items: { | ||
| type: 'object', | ||
| }, | ||
| }, | ||
| count: { | ||
| type: 'number', | ||
| }, | ||
| offset: { | ||
| type: 'number', | ||
| }, | ||
| total: { | ||
| type: 'number', | ||
| }, | ||
| success: { | ||
| type: 'boolean', | ||
| enum: [true], | ||
| } | ||
| }, | ||
| required: ['threads', 'count', 'offset', 'total', 'success'], | ||
| additionalProperties: false, | ||
| }); | ||
|
Comment on lines
+278
to
+358
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical migration gap: After moving Please either (a) keep the rest-typings export until Suggested patch (option b: localize syncThreadMessages validator)@@
import {
@@
- isChatSyncThreadMessagesProps,
@@
} from '@rocket.chat/rest-typings';
@@
+type ChatSyncThreadMessagesLocal = PaginatedRequest<{
+ tmid: IMessage['_id'];
+ updatedSince: string;
+}>;
+
+const ChatSyncThreadMessagesLocalSchema = {
+ type: 'object',
+ properties: {
+ tmid: {
+ type: 'string',
+ minLength: 1,
+ },
+ updatedSince: {
+ type: 'string',
+ format: 'iso-date-time',
+ },
+ },
+ required: ['tmid', 'updatedSince'],
+ additionalProperties: false,
+};
+
+const isChatSyncThreadMessagesLocalProps = ajv.compile<ChatSyncThreadMessagesLocal>(ChatSyncThreadMessagesLocalSchema);
@@
API.v1.addRoute(
'chat.syncThreadMessages',
- { authRequired: true, validateParams: isChatSyncThreadMessagesProps },
+ { authRequired: true, validateParams: isChatSyncThreadMessagesLocalProps },
{🤖 Prompt for AI Agents |
||
|
|
||
| const chatEndpoints = API.v1 | ||
| .post( | ||
| 'chat.pinMessage', | ||
|
|
@@ -558,6 +590,58 @@ const chatEndpoints = API.v1 | |
|
|
||
| return API.v1.success(); | ||
| }, | ||
| ) | ||
| .get( | ||
| 'chat.getThreadsList', | ||
| { | ||
| authRequired: true, | ||
| validateParams: isChatGetThreadsListProps, | ||
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| response: { | ||
| 400: validateBadRequestErrorResponse, | ||
| 401: validateUnauthorizedErrorResponse, | ||
| 200: isChatGetThreadsListResponse, | ||
| }, | ||
| }, | ||
| async function action() { | ||
| const { rid, type, text } = this.queryParams; | ||
|
|
||
| const { offset, count } = await getPaginationItems(this.queryParams); | ||
| const { sort, fields, query } = await this.parseJsonQuery(); | ||
|
|
||
| if (!settings.get<boolean>('Threads_enabled')) { | ||
| throw new Meteor.Error('error-not-allowed', 'Threads Disabled'); | ||
| } | ||
| const user = await Users.findOneById(this.userId, { projection: { _id: 1 } }); | ||
| const room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, t: 1, _id: 1 } }); | ||
|
|
||
| if (!room || !user || !(await canAccessRoomAsync(room, user))) { | ||
| throw new Meteor.Error('error-not-allowed', 'Not Allowed'); | ||
| } | ||
|
|
||
| const typeThread = { | ||
| _hidden: { $ne: true }, | ||
| ...(type === 'following' && { replies: { $in: [this.userId] } }), | ||
| ...(type === 'unread' && { _id: { $in: (await Subscriptions.findOneByRoomIdAndUserId(room._id, user._id))?.tunread || [] } }), | ||
| msg: new RegExp(escapeRegExp(text || ''), 'i'), | ||
| }; | ||
|
|
||
| const threadQuery = { ...query, ...typeThread, rid: room._id, tcount: { $exists: true } }; | ||
| const { cursor, totalCount } = await Messages.findPaginated<IThreadMainMessage>(threadQuery, { | ||
| sort: sort || { tlm: -1 }, | ||
| skip: offset, | ||
| limit: count, | ||
| projection: fields, | ||
| }); | ||
|
|
||
| const [threads, total] = await Promise.all([cursor.toArray(), totalCount]); | ||
|
|
||
| return API.v1.success({ | ||
| threads: await normalizeMessagesForUser(threads, this.userId), | ||
| count: threads.length, | ||
| offset, | ||
| total, | ||
| }); | ||
| }, | ||
| ); | ||
|
|
||
| API.v1.addRoute( | ||
|
|
@@ -782,52 +866,6 @@ API.v1.addRoute( | |
| }, | ||
| ); | ||
|
|
||
| API.v1.addRoute( | ||
| 'chat.getThreadsList', | ||
| { authRequired: true, validateParams: isChatGetThreadsListProps }, | ||
| { | ||
| async get() { | ||
| const { rid, type, text } = this.queryParams; | ||
|
|
||
| const { offset, count } = await getPaginationItems(this.queryParams); | ||
| const { sort, fields, query } = await this.parseJsonQuery(); | ||
|
|
||
| if (!settings.get<boolean>('Threads_enabled')) { | ||
| throw new Meteor.Error('error-not-allowed', 'Threads Disabled'); | ||
| } | ||
| const user = await Users.findOneById(this.userId, { projection: { _id: 1 } }); | ||
| const room = await Rooms.findOneById(rid, { projection: { ...roomAccessAttributes, t: 1, _id: 1 } }); | ||
|
|
||
| if (!room || !user || !(await canAccessRoomAsync(room, user))) { | ||
| throw new Meteor.Error('error-not-allowed', 'Not Allowed'); | ||
| } | ||
|
|
||
| const typeThread = { | ||
| _hidden: { $ne: true }, | ||
| ...(type === 'following' && { replies: { $in: [this.userId] } }), | ||
| ...(type === 'unread' && { _id: { $in: (await Subscriptions.findOneByRoomIdAndUserId(room._id, user._id))?.tunread || [] } }), | ||
| msg: new RegExp(escapeRegExp(text || ''), 'i'), | ||
| }; | ||
|
|
||
| const threadQuery = { ...query, ...typeThread, rid: room._id, tcount: { $exists: true } }; | ||
| const { cursor, totalCount } = await Messages.findPaginated<IThreadMainMessage>(threadQuery, { | ||
| sort: sort || { tlm: -1 }, | ||
| skip: offset, | ||
| limit: count, | ||
| projection: fields, | ||
| }); | ||
|
|
||
| const [threads, total] = await Promise.all([cursor.toArray(), totalCount]); | ||
|
|
||
| return API.v1.success({ | ||
| threads: await normalizeMessagesForUser(threads, this.userId), | ||
| count: threads.length, | ||
| offset, | ||
| total, | ||
| }); | ||
| }, | ||
| }, | ||
| ); | ||
|
|
||
| API.v1.addRoute( | ||
| 'chat.syncThreadsList', | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.