Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/migrate-chat-getPinnedMessages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/rest-typings": minor
---

Add OpenAPI support for the chat.getPinnedMessages API endpoint by migrating to a modern chained route definition syntax and utilizing AJV schemas for query and response validation.
107 changes: 77 additions & 30 deletions apps/meteor/app/api/server/v1/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
isChatSearchProps,
isChatSendMessageProps,
isChatIgnoreUserProps,
isChatGetPinnedMessagesProps,
isChatGetMentionedMessagesProps,
isChatReactProps,
isChatGetDeletedMessagesProps,
Expand Down Expand Up @@ -558,6 +557,83 @@ const chatEndpoints = API.v1

return API.v1.success();
},
)
.get(
'chat.getPinnedMessages',
{
authRequired: true,
query: ajv.compile<{ roomId: string; count?: number; offset?: number; sort?: string }>({
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,
}),
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 { offset, count } = await getPaginationItems(this.queryParams);
const { sort } = await this.parseJsonQuery();

if (!(await canAccessRoomIdAsync(roomId, this.userId))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed');
}

const { cursor, totalCount } = Messages.findPaginatedPinnedByRoom(roomId, {
skip: offset,
limit: count,
sort,
});

const [messages, total] = await Promise.all([cursor.toArray(), totalCount]);

return API.v1.success({
messages: await normalizeMessagesForUser(messages, this.userId),
count: messages.length,
offset,
total,
});
},
);

API.v1.addRoute(
Expand Down Expand Up @@ -753,35 +829,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'chat.getPinnedMessages',
{ authRequired: true, validateParams: isChatGetPinnedMessagesProps },
{
async get() {
const { roomId } = this.queryParams;
const { offset, count } = await getPaginationItems(this.queryParams);

if (!(await canAccessRoomIdAsync(roomId, this.userId))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed');
}

const { cursor, totalCount } = Messages.findPaginatedPinnedByRoom(roomId, {
skip: offset,
limit: count,
});

const [messages, total] = await Promise.all([cursor.toArray(), totalCount]);

return API.v1.success({
messages: await normalizeMessagesForUser(messages, this.userId),
count: messages.length,
offset,
total,
});
},
},
);

API.v1.addRoute(
'chat.getThreadsList',
{ authRequired: true, validateParams: isChatGetThreadsListProps },
Expand Down
41 changes: 0 additions & 41 deletions packages/rest-typings/src/v1/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,39 +529,6 @@ const GetStarredMessagesSchema = {

export const isChatGetStarredMessagesProps = ajv.compile<GetStarredMessages>(GetStarredMessagesSchema);

type GetPinnedMessages = {
roomId: IRoom['_id'];
count?: number;
offset?: number;
sort?: string;
};

const GetPinnedMessagesSchema = {
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 isChatGetPinnedMessagesProps = ajv.compile<GetPinnedMessages>(GetPinnedMessagesSchema);

type GetMentionedMessages = {
roomId: IRoom['_id'];
count?: number;
Expand Down Expand Up @@ -954,14 +921,6 @@ export type ChatEndpoints = {
total: number;
};
};
'/v1/chat.getPinnedMessages': {
GET: (params: GetPinnedMessages) => {
messages: IMessage[];
count: number;
offset: number;
total: number;
};
};
'/v1/chat.getMentionedMessages': {
GET: (params: GetMentionedMessages) => {
messages: IMessage[];
Expand Down