From db76f3b0d254dabbdca82f9121862c222c9fe5a4 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Mon, 16 Mar 2026 13:28:26 +0530 Subject: [PATCH 01/13] refactor(chat): migrate chat.getThreadsList to typed REST endpoint --- apps/meteor/app/api/server/v1/chat.ts | 80 +++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index a00d57e46ae72..c015b11c9ccfa 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -275,6 +275,34 @@ const isChatPinMessageProps = ajv.compile(ChatPinMessageSchema); const isChatUnpinMessageProps = ajv.compile(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', + }, + }, + required: ['threads', 'count', 'offset', 'total'], + additionalProperties: false, +}); + const chatEndpoints = API.v1 .post( 'chat.pinMessage', @@ -558,6 +586,58 @@ const chatEndpoints = API.v1 return API.v1.success(); }, + ) + .get( + 'chat.getThreadsList', + { + authRequired: true, + validateParams: isChatGetThreadsListProps, + 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('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(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( From a70323ac2fae71a660449b7a7d9fb914d2d8910f Mon Sep 17 00:00:00 2001 From: Harxhit Date: Mon, 16 Mar 2026 13:35:56 +0530 Subject: [PATCH 02/13] refactor(chat): remove legacy chat.getThreadsList route --- apps/meteor/app/api/server/v1/chat.ts | 46 --------------------------- 1 file changed, 46 deletions(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index c015b11c9ccfa..38ba6c889641a 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -862,52 +862,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('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(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', From f96897fcc78464df8260049e2de7b334dadc4b48 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Mon, 16 Mar 2026 21:19:44 +0530 Subject: [PATCH 03/13] fix(chat): add missing success field to chat.getThreadsList response schema --- apps/meteor/app/api/server/v1/chat.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index 38ba6c889641a..1976f7272d428 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -298,8 +298,12 @@ const isChatGetThreadsListResponse = ajv.compile<{ total: { type: 'number', }, + success: { + type: 'boolean', + enum: [true], + } }, - required: ['threads', 'count', 'offset', 'total'], + required: ['threads', 'count', 'offset', 'total', 'success'], additionalProperties: false, }); From 257ef258670181138e9f35ba662e3f5bf6012572 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Mon, 16 Mar 2026 21:38:17 +0530 Subject: [PATCH 04/13] fix(chat.getThreadsList): align response type and use query validator --- apps/meteor/app/api/server/v1/chat.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index 1976f7272d428..f6b7131a9728a 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -280,6 +280,7 @@ const isChatGetThreadsListResponse = ajv.compile<{ count: number; offset: number; total: number; + success: boolean; }>({ type: 'object', properties: { @@ -595,7 +596,7 @@ const chatEndpoints = API.v1 'chat.getThreadsList', { authRequired: true, - validateParams: isChatGetThreadsListProps, + query: isChatGetThreadsListProps, response: { 400: validateBadRequestErrorResponse, 401: validateUnauthorizedErrorResponse, From d824760fa63e65ac4edbf9cf8eb0cf7b8cf6dac6 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Tue, 17 Mar 2026 12:33:33 +0530 Subject: [PATCH 05/13] fix(chat): address review feedback for chat.getThreadsList schema and validation --- apps/meteor/app/api/server/v1/chat.ts | 64 ++++++++++++++--- packages/rest-typings/src/v1/chat.ts | 98 +-------------------------- 2 files changed, 57 insertions(+), 105 deletions(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index f6b7131a9728a..c0d5dc6c1c41d 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -1,13 +1,13 @@ import { Message } from '@rocket.chat/core-services'; -import type { IMessage, IThreadMainMessage } from '@rocket.chat/core-typings'; +import type { IMessage, IThreadMainMessage, IRoom } from '@rocket.chat/core-typings'; import { MessageTypes } from '@rocket.chat/message-types'; import { Messages, Users, Rooms, Subscriptions } from '@rocket.chat/models'; +import type { PaginatedRequest } from '@rocket.chat/rest-typings'; import { ajv, isChatReportMessageProps, isChatGetURLPreviewProps, isChatUpdateProps, - isChatGetThreadsListProps, isChatDeleteProps, isChatSyncMessagesProps, isChatGetMessageProps, @@ -275,6 +275,55 @@ const isChatPinMessageProps = ajv.compile(ChatPinMessageSchema); const isChatUnpinMessageProps = ajv.compile(ChatUnpinMessageSchema); +type ChatGetThreadsList = PaginatedRequest<{ + rid: IRoom['_id']; + type?: 'unread' | 'following'; + text?: string; + fields?: string; +}>; + +const ChatGetThreadsListSchema = { + type: 'object', + properties: { + rid: { + type: 'string', + }, + type: { + type: 'string', + enum: ['following', 'unread'], + nullable: true, + }, + text: { + type: 'string', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + count: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, + query: { + type: 'string', + nullable: true, + }, + fields: { + type: 'string', + nullable: true, + }, + }, + required: ['rid'], + additionalProperties: false, +}; + +const isChatGetThreadsListLocalProps = ajv.compile(ChatGetThreadsListSchema); + const isChatGetThreadsListResponse = ajv.compile<{ threads: IMessage[]; count: number; @@ -302,7 +351,7 @@ const isChatGetThreadsListResponse = ajv.compile<{ success: { type: 'boolean', enum: [true], - } + }, }, required: ['threads', 'count', 'offset', 'total', 'success'], additionalProperties: false, @@ -596,7 +645,7 @@ const chatEndpoints = API.v1 'chat.getThreadsList', { authRequired: true, - query: isChatGetThreadsListProps, + query: isChatGetThreadsListLocalProps, response: { 400: validateBadRequestErrorResponse, 401: validateUnauthorizedErrorResponse, @@ -867,7 +916,6 @@ API.v1.addRoute( }, ); - API.v1.addRoute( 'chat.syncThreadsList', { authRequired: true, validateParams: isChatSyncThreadsListProps }, @@ -1089,9 +1137,9 @@ API.v1.addRoute( }, ); + export type ChatEndpoints = ExtractRoutesFromAPI; declare module '@rocket.chat/rest-typings' { - // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface - interface Endpoints extends ChatEndpoints {} -} + interface Endpoints extends ChatEndpoints {} +} \ No newline at end of file diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index b52bba2d61ed5..23ef6b22a2f44 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -1,4 +1,4 @@ -import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl, IThreadMainMessage } from '@rocket.chat/core-typings'; +import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl} from '@rocket.chat/core-typings'; import { ajv } from './Ajv'; import type { PaginatedRequest } from '../helpers/PaginatedRequest'; @@ -146,54 +146,6 @@ const ChatReportMessageSchema = { export const isChatReportMessageProps = ajv.compile(ChatReportMessageSchema); -type ChatGetThreadsList = PaginatedRequest<{ - rid: IRoom['_id']; - type?: 'unread' | 'following'; - text?: string; - fields?: string; -}>; - -const ChatGetThreadsListSchema = { - type: 'object', - properties: { - rid: { - type: 'string', - }, - type: { - type: 'string', - enum: ['following', 'unread'], - nullable: true, - }, - text: { - type: 'string', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, - count: { - type: 'number', - nullable: true, - }, - sort: { - type: 'string', - nullable: true, - }, - query: { - type: 'string', - nullable: true, - }, - fields: { - type: 'string', - nullable: true, - }, - }, - required: ['rid'], - additionalProperties: false, -}; - -export const isChatGetThreadsListProps = ajv.compile(ChatGetThreadsListSchema); type ChatSyncThreadsList = { rid: IRoom['_id']; @@ -638,40 +590,6 @@ const ChatSyncMessagesSchema = { export const isChatSyncMessagesProps = ajv.compile(ChatSyncMessagesSchema); -type ChatSyncThreadMessages = PaginatedRequest<{ - tmid: string; - updatedSince: string; -}>; - -const ChatSyncThreadMessagesSchema = { - type: 'object', - properties: { - tmid: { - type: 'string', - minLength: 1, - }, - updatedSince: { - type: 'string', - format: 'iso-date-time', - }, - count: { - type: 'number', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, - sort: { - type: 'string', - nullable: true, - }, - }, - required: ['tmid', 'updatedSince'], - additionalProperties: false, -}; - -export const isChatSyncThreadMessagesProps = ajv.compile(ChatSyncThreadMessagesSchema); type ChatGetThreadMessages = PaginatedRequest<{ tmid: string; @@ -906,12 +824,6 @@ export type ChatEndpoints = { total: number; }; }; - '/v1/chat.getThreadsList': { - GET: (params: ChatGetThreadsList) => { - threads: IThreadMainMessage[]; - total: number; - }; - }; '/v1/chat.syncThreadsList': { GET: (params: ChatSyncThreadsList) => { threads: { @@ -989,14 +901,6 @@ export type ChatEndpoints = { message: IMessage; }; }; - '/v1/chat.syncThreadMessages': { - GET: (params: ChatSyncThreadMessages) => { - messages: { - update: IMessage[]; - remove: IMessage[]; - }; - }; - }; '/v1/chat.getThreadMessages': { GET: (params: ChatGetThreadMessages) => { messages: IMessage[]; From 74a4189277e55817d117a5b60fd3646cb01f8ffc Mon Sep 17 00:00:00 2001 From: Harxhit Date: Tue, 17 Mar 2026 13:19:12 +0530 Subject: [PATCH 06/13] refactor(chat): migrate chat.getThreadsList to local validation and remove rest-typings usage - moved validation schema and types for chat.getThreadsList to server (local AJV validator) - removed ChatGetThreadsList types, schema, and validator from rest-typings - removed /v1/chat.getThreadsList endpoint typing - ensured other chat endpoints (e.g., syncThreadMessages) remain unchanged --- packages/rest-typings/src/v1/chat.ts | 44 +++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index 23ef6b22a2f44..ac181f98f35af 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -1,4 +1,4 @@ -import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl} from '@rocket.chat/core-typings'; +import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl } from '@rocket.chat/core-typings'; import { ajv } from './Ajv'; import type { PaginatedRequest } from '../helpers/PaginatedRequest'; @@ -590,6 +590,40 @@ const ChatSyncMessagesSchema = { export const isChatSyncMessagesProps = ajv.compile(ChatSyncMessagesSchema); +type ChatSyncThreadMessages = PaginatedRequest<{ + tmid: string; + updatedSince: string; +}>; + +const ChatSyncThreadMessagesSchema = { + type: 'object', + properties: { + tmid: { + type: 'string', + minLength: 1, + }, + updatedSince: { + type: 'string', + format: 'iso-date-time', + }, + count: { + type: 'number', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, + }, + required: ['tmid', 'updatedSince'], + additionalProperties: false, +}; + +export const isChatSyncThreadMessagesProps = ajv.compile(ChatSyncThreadMessagesSchema); type ChatGetThreadMessages = PaginatedRequest<{ tmid: string; @@ -901,6 +935,14 @@ export type ChatEndpoints = { message: IMessage; }; }; + '/v1/chat.syncThreadMessages': { + GET: (params: ChatSyncThreadMessages) => { + messages: { + update: IMessage[]; + remove: IMessage[]; + }; + }; + }; '/v1/chat.getThreadMessages': { GET: (params: ChatGetThreadMessages) => { messages: IMessage[]; From ae953d12b5c2acd5fdd5f5f2de629d9572a5f585 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Tue, 17 Mar 2026 13:43:18 +0530 Subject: [PATCH 07/13] fix(chat): align chat.syncThreadMessages typing and schema with delta-sync behavior --- packages/rest-typings/src/v1/chat.ts | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index ac181f98f35af..b769167724307 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -590,10 +590,10 @@ const ChatSyncMessagesSchema = { export const isChatSyncMessagesProps = ajv.compile(ChatSyncMessagesSchema); -type ChatSyncThreadMessages = PaginatedRequest<{ +type ChatSyncThreadMessages = { tmid: string; updatedSince: string; -}>; +}; const ChatSyncThreadMessagesSchema = { type: 'object', @@ -606,18 +606,6 @@ const ChatSyncThreadMessagesSchema = { type: 'string', format: 'iso-date-time', }, - count: { - type: 'number', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, - sort: { - type: 'string', - nullable: true, - }, }, required: ['tmid', 'updatedSince'], additionalProperties: false, From 13213901f316ca71a0726b15beb5e3268a5cf01d Mon Sep 17 00:00:00 2001 From: Harxhit Date: Wed, 18 Mar 2026 22:18:58 +0530 Subject: [PATCH 08/13] refactor: update schema and adjust tests for new query format --- .changeset/smooth-donkeys-add.md | 5 +++++ apps/meteor/app/api/server/v1/chat.ts | 2 +- apps/meteor/tests/end-to-end/api/chat.ts | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/smooth-donkeys-add.md diff --git a/.changeset/smooth-donkeys-add.md b/.changeset/smooth-donkeys-add.md new file mode 100644 index 0000000000000..8079d0bc87ece --- /dev/null +++ b/.changeset/smooth-donkeys-add.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +migrated chat.getThreadsList to typed REST Point diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index c0d5dc6c1c41d..032e7dfb788eb 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -336,7 +336,7 @@ const isChatGetThreadsListResponse = ajv.compile<{ threads: { type: 'array', items: { - type: 'object', + ref: '#/components/schemas/IMessage', }, }, count: { diff --git a/apps/meteor/tests/end-to-end/api/chat.ts b/apps/meteor/tests/end-to-end/api/chat.ts index 15ab7e4c083cb..cf07320c69e62 100644 --- a/apps/meteor/tests/end-to-end/api/chat.ts +++ b/apps/meteor/tests/end-to-end/api/chat.ts @@ -4065,7 +4065,7 @@ describe('Threads', () => { .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('errorType', 'invalid-params'); + expect(res.body).to.have.property('errorType', 'error-invalid-params'); }); }); @@ -4081,7 +4081,7 @@ describe('Threads', () => { .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body).to.have.property('errorType', 'invalid-params'); + expect(res.body).to.have.property('errorType', 'error-invalid-params'); }); }); From 94f9c5ad3996bb9b94b3909433bc2b61fd1da097 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Thu, 19 Mar 2026 01:51:59 +0530 Subject: [PATCH 09/13] fix: Changes in schema ref -> $ref --- apps/meteor/app/api/server/v1/chat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index 032e7dfb788eb..ee64ea1fef0db 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -336,7 +336,7 @@ const isChatGetThreadsListResponse = ajv.compile<{ threads: { type: 'array', items: { - ref: '#/components/schemas/IMessage', + $ref: '#/components/schemas/IMessage', }, }, count: { From dd0ecc97c6a08a54f8ef1f7a25709fb60b5f2e06 Mon Sep 17 00:00:00 2001 From: Harxhit Date: Thu, 19 Mar 2026 18:49:04 +0530 Subject: [PATCH 10/13] fix:Added rest-typings and updated .changset to patch-> minor --- .changeset/sour-baboons-judge.md | 5 ++ packages/rest-typings/src/v1/chat.ts | 73 ++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 .changeset/sour-baboons-judge.md diff --git a/.changeset/sour-baboons-judge.md b/.changeset/sour-baboons-judge.md new file mode 100644 index 0000000000000..3976066648d1e --- /dev/null +++ b/.changeset/sour-baboons-judge.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +Migrated chat.getThreadsList to typed REST endpoint diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index 82e902dbdcc0c..f3a6e61f677b0 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -1,4 +1,4 @@ -import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl } from '@rocket.chat/core-typings'; +import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl, IThreadMainMessage } from '@rocket.chat/core-typings'; import { ajv, ajvQuery } from './Ajv'; import type { PaginatedRequest } from '../helpers/PaginatedRequest'; @@ -146,6 +146,55 @@ const ChatReportMessageSchema = { export const isChatReportMessageProps = ajv.compile(ChatReportMessageSchema); +type ChatGetThreadsList = PaginatedRequest<{ + rid: IRoom['_id']; + type?: 'unread' | 'following'; + text?: string; + fields?: string; +}>; + +const ChatGetThreadsListSchema = { + type: 'object', + properties: { + rid: { + type: 'string', + }, + type: { + type: 'string', + enum: ['following', 'unread'], + nullable: true, + }, + text: { + type: 'string', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + count: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, + query: { + type: 'string', + nullable: true, + }, + fields: { + type: 'string', + nullable: true, + }, + }, + required: ['rid'], + additionalProperties: false, +}; + +export const isChatGetThreadsListProps = ajvQuery.compile(ChatGetThreadsListSchema); + type ChatSyncThreadsList = { rid: IRoom['_id']; updatedSince: string; @@ -589,10 +638,10 @@ const ChatSyncMessagesSchema = { export const isChatSyncMessagesProps = ajvQuery.compile(ChatSyncMessagesSchema); -type ChatSyncThreadMessages = { +type ChatSyncThreadMessages = PaginatedRequest<{ tmid: string; updatedSince: string; -}; +}>; const ChatSyncThreadMessagesSchema = { type: 'object', @@ -605,6 +654,18 @@ const ChatSyncThreadMessagesSchema = { type: 'string', format: 'iso-date-time', }, + count: { + type: 'number', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, }, required: ['tmid', 'updatedSince'], additionalProperties: false, @@ -845,6 +906,12 @@ export type ChatEndpoints = { total: number; }; }; + '/v1/chat.getThreadsList': { + GET: (params: ChatGetThreadsList) => { + threads: IThreadMainMessage[]; + total: number; + }; + }; '/v1/chat.syncThreadsList': { GET: (params: ChatSyncThreadsList) => { threads: { From ae055a8e6d7ee8274184a9f0d940615dd71a503b Mon Sep 17 00:00:00 2001 From: Harxhit Date: Fri, 20 Mar 2026 14:13:36 +0530 Subject: [PATCH 11/13] fix: Added changeset --- .changeset/soft-peas-mate.md | 6 +++ packages/rest-typings/src/v1/chat.ts | 57 +--------------------------- 2 files changed, 7 insertions(+), 56 deletions(-) create mode 100644 .changeset/soft-peas-mate.md diff --git a/.changeset/soft-peas-mate.md b/.changeset/soft-peas-mate.md new file mode 100644 index 0000000000000..6086511f69e61 --- /dev/null +++ b/.changeset/soft-peas-mate.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/rest-typings': minor +'@rocket.chat/meteor': minor +--- + +Migrated chat.getThreadsList existing old REST API structure to new typed REST (openAPI) structure diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index f3a6e61f677b0..66de89872bbe0 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -1,4 +1,4 @@ -import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl, IThreadMainMessage } from '@rocket.chat/core-typings'; +import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl } from '@rocket.chat/core-typings'; import { ajv, ajvQuery } from './Ajv'; import type { PaginatedRequest } from '../helpers/PaginatedRequest'; @@ -146,55 +146,6 @@ const ChatReportMessageSchema = { export const isChatReportMessageProps = ajv.compile(ChatReportMessageSchema); -type ChatGetThreadsList = PaginatedRequest<{ - rid: IRoom['_id']; - type?: 'unread' | 'following'; - text?: string; - fields?: string; -}>; - -const ChatGetThreadsListSchema = { - type: 'object', - properties: { - rid: { - type: 'string', - }, - type: { - type: 'string', - enum: ['following', 'unread'], - nullable: true, - }, - text: { - type: 'string', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, - count: { - type: 'number', - nullable: true, - }, - sort: { - type: 'string', - nullable: true, - }, - query: { - type: 'string', - nullable: true, - }, - fields: { - type: 'string', - nullable: true, - }, - }, - required: ['rid'], - additionalProperties: false, -}; - -export const isChatGetThreadsListProps = ajvQuery.compile(ChatGetThreadsListSchema); - type ChatSyncThreadsList = { rid: IRoom['_id']; updatedSince: string; @@ -906,12 +857,6 @@ export type ChatEndpoints = { total: number; }; }; - '/v1/chat.getThreadsList': { - GET: (params: ChatGetThreadsList) => { - threads: IThreadMainMessage[]; - total: number; - }; - }; '/v1/chat.syncThreadsList': { GET: (params: ChatSyncThreadsList) => { threads: { From f57fa3f9099f109ccbfc8b8ca00099da12dfad7f Mon Sep 17 00:00:00 2001 From: Harshit Singh Parihar Date: Fri, 20 Mar 2026 14:24:55 +0530 Subject: [PATCH 12/13] Delete .changeset/sour-baboons-judge.md --- .changeset/sour-baboons-judge.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/sour-baboons-judge.md diff --git a/.changeset/sour-baboons-judge.md b/.changeset/sour-baboons-judge.md deleted file mode 100644 index 3976066648d1e..0000000000000 --- a/.changeset/sour-baboons-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': minor ---- - -Migrated chat.getThreadsList to typed REST endpoint From 8aaca4fc41a8858098001dd791f90328850eb23b Mon Sep 17 00:00:00 2001 From: Harshit Singh Parihar Date: Fri, 20 Mar 2026 14:25:32 +0530 Subject: [PATCH 13/13] Delete .changeset/smooth-donkeys-add.md Reviewer said we use minor not patch --- .changeset/smooth-donkeys-add.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/smooth-donkeys-add.md diff --git a/.changeset/smooth-donkeys-add.md b/.changeset/smooth-donkeys-add.md deleted file mode 100644 index 8079d0bc87ece..0000000000000 --- a/.changeset/smooth-donkeys-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rocket.chat/meteor': patch ---- - -migrated chat.getThreadsList to typed REST Point