diff --git a/.changeset/rare-waves-help.md b/.changeset/rare-waves-help.md new file mode 100644 index 0000000000000..1406344ae4ec8 --- /dev/null +++ b/.changeset/rare-waves-help.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Add OpenAPI support for the Rocket.Chat users.getAvatarSuggestion API endpoints by migrating to a modern chained route definition syntax and utilizing shared AJV schemas for validation to enhance API documentation and ensure type safety through response validation. diff --git a/apps/meteor/app/api/server/v1/users.ts b/apps/meteor/app/api/server/v1/users.ts index b418d555761fd..5b831214d6a22 100644 --- a/apps/meteor/app/api/server/v1/users.ts +++ b/apps/meteor/app/api/server/v1/users.ts @@ -19,6 +19,7 @@ import { isUsersCheckUsernameAvailabilityParamsGET, isUsersSendConfirmationEmailParamsPOST, } from '@rocket.chat/rest-typings'; +import { ajv } from '@rocket.chat/rest-typings/src/v1/Ajv'; import { getLoginExpirationInMs, wrapExceptions } from '@rocket.chat/tools'; import { Accounts } from 'meteor/accounts-base'; import { Match, check } from 'meteor/check'; @@ -68,6 +69,7 @@ import { deleteUserOwnAccount } from '../../../lib/server/methods/deleteUserOwnA import { settings } from '../../../settings/server'; import { isSMTPConfigured } from '../../../utils/server/functions/isSMTPConfigured'; import { getURL } from '../../../utils/server/getURL'; +import type { ExtractRoutesFromAPI } from '../ApiClass'; import { API } from '../api'; import { getPaginationItems } from '../helpers/getPaginationItems'; import { getUserFromParams } from '../helpers/getUserFromParams'; @@ -94,17 +96,93 @@ API.v1.addRoute( }, ); -API.v1.addRoute( +const usersGetAvatarSuggestionEndpoints = API.v1.get( 'users.getAvatarSuggestion', { authRequired: true, + response: { + 400: ajv.compile<{ + error?: string; + errorType?: string; + stack?: string; + details?: string; + }>({ + type: 'object', + properties: { + success: { type: 'boolean', enum: [false] }, + stack: { type: 'string' }, + error: { type: 'string' }, + errorType: { type: 'string' }, + details: { type: 'string' }, + }, + required: ['success'], + additionalProperties: false, + }), + 401: ajv.compile({ + type: 'object', + properties: { + success: { + type: 'boolean', + enum: [false], + }, + status: { type: 'string' }, + message: { type: 'string' }, + error: { type: 'string' }, + errorType: { type: 'string' }, + }, + required: ['success'], + additionalProperties: false, + }), + 200: ajv.compile<{ + suggestions: Record< + string, + { + blob: string; + contentType: string; + service: string; + url: string; + } + >; + }>({ + type: 'object', + properties: { + success: { + type: 'boolean', + enum: [true], + }, + suggestions: { + type: 'object', + additionalProperties: { + type: 'object', + properties: { + blob: { + type: 'string', + }, + contentType: { + type: 'string', + }, + service: { + type: 'string', + }, + url: { + type: 'string', + format: 'uri', + }, + }, + required: ['blob', 'contentType', 'service', 'url'], + additionalProperties: false, + }, + }, + }, + required: ['success', 'suggestions'], + additionalProperties: false, + }), + }, }, - { - async get() { - const suggestions = await getAvatarSuggestionForUser(this.user); + async function action() { + const suggestions = await getAvatarSuggestionForUser(this.user); - return API.v1.success({ suggestions }); - }, + return API.v1.success({ suggestions }); }, ); @@ -1424,3 +1502,12 @@ settings.watch('Rate_Limiter_Limit_RegisterUser', (value) => { API.v1.updateRateLimiterDictionaryForRoute(userRegisterRoute, value); }); + +type UsersGetAvatarSuggestionEndpoints = ExtractRoutesFromAPI; + +export type UsersEndpoints = UsersGetAvatarSuggestionEndpoints; + +declare module '@rocket.chat/rest-typings' { + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface + interface Endpoints extends UsersGetAvatarSuggestionEndpoints {} +} diff --git a/packages/rest-typings/src/v1/users.ts b/packages/rest-typings/src/v1/users.ts index 6d4e62331bcf8..fddf1bf5c11a3 100644 --- a/packages/rest-typings/src/v1/users.ts +++ b/packages/rest-typings/src/v1/users.ts @@ -259,20 +259,6 @@ export type UsersEndpoints = { }; }; - '/v1/users.getAvatarSuggestion': { - GET: () => { - suggestions: Record< - string, - { - blob: string; - contentType: string; - service: string; - url: string; - } - >; - }; - }; - '/v1/users.checkUsernameAvailability': { GET: (params: { username: string }) => { result: boolean;