diff --git a/apps/meteor/app/api/server/definition.spec.ts b/apps/meteor/app/api/server/definition.spec.ts new file mode 100644 index 0000000000000..3c659820b34b3 --- /dev/null +++ b/apps/meteor/app/api/server/definition.spec.ts @@ -0,0 +1,73 @@ +import type { IUser } from '@rocket.chat/core-typings'; +import type { ValidateFunction } from 'ajv'; + +import type { TypedThis, TypedOptions, Action, InnerAction } from './definition'; + +// --- Utilities --- +type IsTypeEqual = (() => T extends A ? 1 : 2) extends () => T extends B ? 1 : 2 ? true : false; +type ExtractThis = T extends (this: infer U, ...args: any[]) => any ? U : never; +type Mutable = { -readonly [K in keyof T]: T[K] }; + +// --- Scenario: POST /v1/chat.postMessage --- +interface IChatPostMessageBody { + channal: string; + text: string; + attachments?: Array<{ + text: string; + color?: string; + image_url?: string; + }>; +} +type ChatPostMessageBodyValidator = ValidateFunction; + +type ChatPostMessageOptions = TypedOptions & { + body: ChatPostMessageBodyValidator; + authRequired: true; +}; + +type Post = 'POST'; +type Path = '/v1/chat.postMessage'; +type Options = ChatPostMessageOptions; + +// --- Expected ActionThis shape (single source of truth) --- +type ExpectedActionThis = { + route: string; + readonly requestIp: string; + urlParams: never; + readonly response: Response; + readonly queryParams: Record; + readonly bodyParams: ChatPostMessageBodyValidator; + readonly request: Request; + readonly queryOperations: never; + parseJsonQuery: () => Promise<{ + sort: Record; + fields: Record; + query: Record; + }>; + readonly connection: { + token: string; + id: string; + close: () => void; + clientAddress: string; + httpHeaders: Record; + }; + user: IUser; + userId: string; + readonly token: string; +}; + +// --- Type-level assertions --- +type ChatPostMessageThis = TypedThis; +type TestChatPostMessageBodyParams = IsTypeEqual; +true satisfies TestChatPostMessageBodyParams; + +type ActionType = Action; +type ActionThisType = ExtractThis>; +type TestActionBodyParams = IsTypeEqual; +true satisfies TestActionBodyParams; + +type InnerActionType = InnerAction; +type ExpectedInnerActionThis = Mutable; +type InnerActionThisType = ExtractThis>; +type TestInnerActionBodyParams = IsTypeEqual; +true satisfies TestInnerActionBodyParams;