Files
upstream-rocketchat/apps/meteor/server/api/definition.ts
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

372 lines
12 KiB
TypeScript

import type { IncomingMessage } from 'node:http';
import type { IUser, LicenseModule, RequiredField } from '@rocket.chat/core-typings';
import type { Logger } from '@rocket.chat/logger';
import type { Method, MethodOf, OperationParams, OperationResult, PathPattern, UrlParams } from '@rocket.chat/rest-typings';
import type { ValidateFunction } from 'ajv';
import type { ITwoFactorOptions } from '../lib/2fa/code';
import type { DeprecationLoggerNextPlannedVersion } from '../lib/deprecationWarningLogger';
export type SuccessStatusCodes = Exclude<Range<208>, Range<200>>;
export type RedirectStatusCodes = Exclude<Range<308>, Range<300>>;
export type AuthorizationStatusCodes = Exclude<Range<451>, Range<400>>;
export type ErrorStatusCodes = Exclude<Exclude<Range<511>, Range<500>>, 509>;
export type SuccessResult<T, TStatusCode extends SuccessStatusCodes = 200> = {
statusCode: TStatusCode;
body: T extends Record<string, unknown> ? { success: true } & T : T;
};
export type FailureResult<T, TStack = undefined, TErrorType = undefined, TErrorDetails = undefined> = {
statusCode: 400;
body: T extends object
? { success: false } & T
: {
success: false;
error?: T;
stack?: TStack;
errorType?: TErrorType;
details?: TErrorDetails;
message?: string;
} & (undefined extends TErrorType ? object : { errorType: TErrorType }) &
(undefined extends TErrorDetails ? object : { details: TErrorDetails extends string ? unknown : TErrorDetails });
};
export type RedirectResult<T, TStatusCode extends RedirectStatusCodes = 300> = {
statusCode: TStatusCode;
body: T;
};
export type UnauthorizedResult<T> = {
statusCode: 401;
body: {
success: false;
error: T | 'unauthorized';
};
};
export type ForbiddenResult<T> = {
statusCode: 403;
body: {
success: false;
// TODO: MAJOR remove 'unauthorized'
error: T | 'forbidden' | 'unauthorized';
};
};
export type TooManyRequestsResult<T> = {
statusCode: 429;
body: {
success: false;
error: T | 'Too many requests';
};
};
export type InternalError<T, StatusCode extends ErrorStatusCodes = 500, D = 'Internal server error'> = {
statusCode: StatusCode;
body: {
error: T | D;
success: false;
};
};
export type UnavailableResult<T, StatusCode = 503> = {
statusCode: StatusCode;
body: {
error: T | 'Service Unavailable';
success: false;
};
};
export type NotFoundResult<T = string> = {
statusCode: 404;
body: {
success: false;
error: T;
};
};
export type TOperation = 'hasAll' | 'hasAny';
export type NonEnterpriseTwoFactorOptions = {
authRequired: true;
forceTwoFactorAuthenticationForNonEnterprise: true;
twoFactorRequired: true;
permissionsRequired?: string[] | { [key in Method]: string[] } | { [key in Method]: { operation: TOperation; permissions: string[] } };
twoFactorOptions: ITwoFactorOptions;
};
export type RateLimiterOptions = {
numRequestsAllowed?: number;
intervalTimeInMS?: number;
bypassPermissions?: string[];
};
export type Options = SharedOptions<'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'>;
export type SharedOptions<TMethod extends string> = (
| {
permissionsRequired?:
| string[]
| ({ [key in TMethod]?: string[] } & { '*'?: string[] })
| ({ [key in TMethod]?: { operation: TOperation; permissions: string[] } } & {
'*'?: { operation: TOperation; permissions: string[] };
});
authRequired?: boolean;
userWithoutUsername?: boolean;
forceTwoFactorAuthenticationForNonEnterprise?: boolean;
rateLimiterOptions?: RateLimiterOptions | boolean;
queryOperations?: string[];
queryFields?: string[];
}
| {
permissionsRequired?:
| string[]
| ({ [key in TMethod]?: string[] } & { '*'?: string[] })
| ({ [key in TMethod]?: { operation: TOperation; permissions: string[] } } & {
'*'?: { operation: TOperation; permissions: string[] };
});
authRequired: true;
userWithoutUsername?: boolean;
twoFactorRequired: true;
twoFactorOptions?: ITwoFactorOptions;
rateLimiterOptions?: RateLimiterOptions | boolean;
queryOperations?: string[];
queryFields?: string[];
}
) & {
/**
* @deprecated The `validateParams` option is deprecated. Use `query` and/OR `body` instead.
*/
validateParams?: ValidateFunction | { [key in TMethod]?: ValidateFunction };
authOrAnonRequired?: true;
deprecation?: {
version: DeprecationLoggerNextPlannedVersion;
alternatives?: PathPattern[];
};
applyMeteorContext?: boolean;
};
export type GenericRouteExecutionContext = ActionThis<any, any, any>;
export type RouteExecutionContext<TMethod extends Method, TPathPattern extends PathPattern, TOptions> = ActionThis<
TMethod,
TPathPattern,
TOptions
>;
export type ActionThis<TMethod extends Method, TPathPattern extends PathPattern, TOptions> = {
readonly logger: Logger;
route: string;
readonly requestIp: string;
urlParams: UrlParams<TPathPattern>;
readonly response: Response;
// TODO make it unsafe
readonly queryParams: TMethod extends 'GET'
? TOptions extends { validateParams: ValidateFunction<infer T> }
? T
: TOptions extends { validateParams: { GET: ValidateFunction<infer T> } }
? T
: Partial<OperationParams<TMethod, TPathPattern>> & { offset?: number; count?: number }
: Record<string, string>;
// TODO make it unsafe
readonly bodyParams: TMethod extends 'GET'
? Record<string, unknown>
: TOptions extends { validateParams: ValidateFunction<infer T> }
? T
: TOptions extends { validateParams: infer V }
? V extends { [key in TMethod]: ValidateFunction<infer T> }
? T
: Partial<OperationParams<TMethod, TPathPattern>>
: // TODO remove the extra (optionals) params when all the endpoints that use these are typed correctly
Partial<OperationParams<TMethod, TPathPattern>>;
readonly request: Request;
readonly incoming: IncomingMessage;
readonly queryOperations: TOptions extends { queryOperations: infer T } ? T : never;
readonly queryFields: TOptions extends { queryFields: infer T } ? T : never;
readonly twoFactorChecked: boolean;
parseJsonQuery(): Promise<{
sort: Record<string, 1 | -1>;
/**
* @deprecated To access "fields" parameter, use ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS environment variable.
*/
fields: Record<string, 0 | 1>;
/**
* @deprecated To access "query" parameter, use ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS environment variable.
*/
query: Record<string, unknown>;
}>;
readonly connection: {
token: string;
id: string;
close: () => void;
clientAddress: string;
httpHeaders: Record<string, any>;
};
} & (TOptions extends { authRequired: true }
? {
user: TOptions extends { userWithoutUsername: true } ? IUser : RequiredField<IUser, 'username'>;
userId: string;
readonly token: string;
}
: TOptions extends { authOrAnonRequired: true }
? {
user?: TOptions extends { userWithoutUsername: true } ? IUser : RequiredField<IUser, 'username'>;
userId?: string;
readonly token?: string;
}
: {
user?: TOptions extends { userWithoutUsername: true } ? IUser : RequiredField<IUser, 'username'>;
userId?: string;
readonly token?: string;
});
export type ResultFor<TMethod extends Method, TPathPattern extends PathPattern> = (
| SuccessResult<OperationResult<TMethod, TPathPattern>>
| FailureResult<unknown, unknown, unknown, unknown>
| UnauthorizedResult<unknown>
| NotFoundResult
| {
statusCode: number;
body: unknown;
}
) & {
headers?: Record<string, string>;
};
export type Action<TMethod extends Method, TPathPattern extends PathPattern, TOptions> =
| ((this: ActionThis<TMethod, TPathPattern, TOptions>) => Promise<ResultFor<TMethod, TPathPattern>>)
| ((this: ActionThis<TMethod, TPathPattern, TOptions>) => ResultFor<TMethod, TPathPattern>);
export type InnerAction<TMethod extends Method, TPathPattern extends PathPattern, TOptions> =
Action<TMethod, TPathPattern, TOptions> extends (this: infer This) => infer Result
? This extends ActionThis<TMethod, TPathPattern, TOptions>
? (this: Mutable<This>) => Result
: never
: never;
type Mutable<Immutable> = {
-readonly [key in keyof Immutable]: Immutable[key];
};
type Operation<TMethod extends Method, TPathPattern extends PathPattern, TEndpointOptions> =
| Action<TMethod, TPathPattern, TEndpointOptions>
| ({
action: Action<TMethod, TPathPattern, TEndpointOptions>;
} & { twoFactorRequired: boolean });
type ActionOperation<TMethod extends Method, TPathPattern extends PathPattern, TEndpointOptions extends Options = object> = {
action: Action<TMethod, TPathPattern, TEndpointOptions>;
} & TEndpointOptions;
export type Operations<TPathPattern extends PathPattern, TOptions extends Options = object> = {
[M in MethodOf<TPathPattern> as Lowercase<M>]: Operation<Uppercase<M>, TPathPattern, TOptions>;
};
export type ActionOperations<TPathPattern extends PathPattern, TOptions extends Options = object> = {
[M in MethodOf<TPathPattern> as Lowercase<M>]: ActionOperation<Uppercase<M>, TPathPattern, TOptions>;
};
type Range<N extends number, Result extends number[] = []> = Result['length'] extends N
? Result[number]
: Range<N, [...Result, Result['length']]>;
type HTTPStatusCodes = SuccessStatusCodes | RedirectStatusCodes | AuthorizationStatusCodes | ErrorStatusCodes;
export type TypedOptions = {
response: {
[K in HTTPStatusCodes]?: ValidateFunction;
};
query?: ValidateFunction;
body?: ValidateFunction;
tags?: string[];
typed?: boolean;
license?: LicenseModule[];
} & SharedOptions<'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'>;
export type TypedThis<TOptions extends TypedOptions, TPath extends string = ''> = {
readonly logger: Logger;
userId: TOptions['authRequired'] extends true ? string : string | undefined;
token: TOptions['authRequired'] extends true ? string : string | undefined;
queryParams: TOptions['query'] extends ValidateFunction<infer Query> ? Query : never;
urlParams: UrlParams<TPath> extends Record<any, any> ? UrlParams<TPath> : never;
parseJsonQuery(): Promise<{
sort: Record<string, 1 | -1>;
/**
* @deprecated To access "fields" parameter, use ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS environment variable.
*/
fields: Record<string, 0 | 1>;
/**
* @deprecated To access "query" parameter, use ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS environment variable.
*/
query: Record<string, unknown>;
}>;
bodyParams: TOptions['body'] extends ValidateFunction<infer Body> ? Body : never;
request: Request;
requestIp?: string;
route: string;
response: Response;
readonly queryOperations: TOptions extends { queryOperations: infer T } ? T : never;
readonly queryFields: TOptions extends { queryFields: infer T } ? T : never;
readonly connection: {
token: string;
id: string;
close: () => void;
clientAddress: string;
httpHeaders: Record<string, string>;
};
readonly twoFactorChecked: boolean;
} & (TOptions['authRequired'] extends true
? {
user: TOptions extends { userWithoutUsername: true } ? IUser : RequiredField<IUser, 'username'>;
}
: {
user?: TOptions extends { userWithoutUsername: true } ? IUser : RequiredField<IUser, 'username'>;
});
type PromiseOrValue<T> = T | Promise<T>;
type InferResult<TResult> = TResult extends ValidateFunction<infer T> ? T : TResult;
type InferNon200Result<T> =
InferResult<T> extends {
success: false;
error?: infer TError;
}
? TError
: never;
type Results<TResponse extends TypedOptions['response']> = {
[K in keyof TResponse]: K extends SuccessStatusCodes
? SuccessResult<InferResult<TResponse[200]>, K>
: K extends RedirectStatusCodes
? RedirectResult<InferNon200Result<TResponse[300]>, K>
: K extends 400
? FailureResult<InferResult<TResponse[400]>>
: K extends 401
? UnauthorizedResult<InferNon200Result<TResponse[401]>>
: K extends 403
? ForbiddenResult<InferNon200Result<TResponse[403]>>
: K extends 404
? NotFoundResult<InferNon200Result<TResponse[404]>>
: K extends ErrorStatusCodes
? InternalError<InferNon200Result<TResponse[K]>, K>
: never;
}[keyof TResponse] & {
headers?: Record<string, string>;
};
export type TypedAction<
TOptions extends TypedOptions,
TPath extends string = '',
TThis extends TypedThis<TOptions, TPath> = TypedThis<TOptions, TPath>,
> = (this: TThis, request: Request) => PromiseOrValue<Results<TOptions['response']>>;