diff --git a/.changeset/migrate-chat-getStarredMessages.md b/.changeset/migrate-chat-getStarredMessages.md new file mode 100644 index 0000000000000..177f98cd7065c --- /dev/null +++ b/.changeset/migrate-chat-getStarredMessages.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": minor +"@rocket.chat/rest-typings": minor +--- + +Add OpenAPI support for the chat.getStarredMessages API endpoint by migrating to a modern chained route definition syntax and utilizing AJV schemas for query and response validation. diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index a00d57e46ae72..711b95838fa38 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -22,7 +22,6 @@ import { isChatSyncThreadsListProps, isChatGetThreadMessagesProps, isChatSyncThreadMessagesProps, - isChatGetStarredMessagesProps, isChatGetDiscussionsProps, validateBadRequestErrorResponse, validateUnauthorizedErrorResponse, @@ -275,6 +274,39 @@ const isChatPinMessageProps = ajv.compile(ChatPinMessageSchema); const isChatUnpinMessageProps = ajv.compile(ChatUnpinMessageSchema); +type GetStarredMessages = { + roomId: string; + count?: number; + offset?: number; + sort?: string; +}; + +const GetStarredMessagesSchema = { + type: 'object', + properties: { + roomId: { + type: 'string', + minLength: 1, + }, + count: { + type: 'number', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, + }, + required: ['roomId'], + additionalProperties: false, +}; + +const isChatGetStarredMessagesProps = ajv.compile(GetStarredMessagesSchema); + const chatEndpoints = API.v1 .post( 'chat.pinMessage', @@ -558,6 +590,56 @@ const chatEndpoints = API.v1 return API.v1.success(); }, + ) + .get( + 'chat.getStarredMessages', + { + authRequired: true, + query: isChatGetStarredMessagesProps, + response: { + 200: ajv.compile<{ messages: IMessage[]; count: number; offset: number; total: number }>({ + type: 'object', + properties: { + messages: { + type: 'array', + items: { + $ref: '#/components/schemas/IMessage', + }, + }, + count: { type: 'number' }, + offset: { type: 'number' }, + total: { type: 'number' }, + success: { + type: 'boolean', + enum: [true], + }, + }, + required: ['messages', 'count', 'offset', 'total', 'success'], + additionalProperties: false, + }), + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + }, + }, + async function action() { + const { roomId } = this.queryParams; + const { sort } = await this.parseJsonQuery(); + const { offset, count } = await getPaginationItems(this.queryParams); + + const messages = await findStarredMessages({ + uid: this.userId, + roomId, + pagination: { + offset, + count, + sort, + }, + }); + + messages.messages = await normalizeMessagesForUser(messages.messages, this.userId); + + return API.v1.success(messages); + }, ); API.v1.addRoute( @@ -981,32 +1063,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'chat.getStarredMessages', - { authRequired: true, validateParams: isChatGetStarredMessagesProps }, - { - async get() { - const { roomId } = this.queryParams; - const { sort } = await this.parseJsonQuery(); - const { offset, count } = await getPaginationItems(this.queryParams); - - const messages = await findStarredMessages({ - uid: this.userId, - roomId, - pagination: { - offset, - count, - sort, - }, - }); - - messages.messages = await normalizeMessagesForUser(messages.messages, this.userId); - - return API.v1.success(messages); - }, - }, -); - API.v1.addRoute( 'chat.getDiscussions', { authRequired: true, validateParams: isChatGetDiscussionsProps }, diff --git a/apps/meteor/tests/end-to-end/api/chat.ts b/apps/meteor/tests/end-to-end/api/chat.ts index 7fd725ed5bfbc..3bfbaebd8cfc2 100644 --- a/apps/meteor/tests/end-to-end/api/chat.ts +++ b/apps/meteor/tests/end-to-end/api/chat.ts @@ -3475,7 +3475,7 @@ describe('[Chat]', () => { .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body.errorType).to.be.equal('invalid-params'); + expect(res.body.errorType).to.be.equal('error-invalid-params'); }) .end(done); }); diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index b52bba2d61ed5..57f9894d5b204 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -496,39 +496,6 @@ const ChatGetMessageReadReceiptsSchema = { export const isChatGetMessageReadReceiptsProps = ajv.compile(ChatGetMessageReadReceiptsSchema); -type GetStarredMessages = { - roomId: IRoom['_id']; - count?: number; - offset?: number; - sort?: string; -}; - -const GetStarredMessagesSchema = { - type: 'object', - properties: { - roomId: { - type: 'string', - minLength: 1, - }, - count: { - type: 'number', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, - sort: { - type: 'string', - nullable: true, - }, - }, - required: ['roomId'], - additionalProperties: false, -}; - -export const isChatGetStarredMessagesProps = ajv.compile(GetStarredMessagesSchema); - type GetPinnedMessages = { roomId: IRoom['_id']; count?: number; @@ -946,14 +913,6 @@ export type ChatEndpoints = { '/v1/chat.getMessageReadReceipts': { GET: (params: ChatGetMessageReadReceipts) => { receipts: IReadReceiptWithUser[] }; }; - '/v1/chat.getStarredMessages': { - GET: (params: GetStarredMessages) => { - messages: IMessage[]; - count: number; - offset: number; - total: number; - }; - }; '/v1/chat.getPinnedMessages': { GET: (params: GetPinnedMessages) => { messages: IMessage[];