UNPKG

exstack

Version:

A utility library designed to simplify and enhance Express.js applications.

881 lines (879 loc) 29.5 kB
import { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response, Router } from "express"; //#region src/enums.d.ts /** * Enum representing HTTP status codes. * * @publicApi http-status code */ declare const HttpStatus: Readonly<{ /** Continue with the request. */ CONTINUE: 100; '100_NAME': "CONTINUE"; /** Switching protocols. */ SWITCHING_PROTOCOLS: 101; '101_NAME': "SWITCHING_PROTOCOLS"; /** Request is being processed. */ PROCESSING: 102; '102_NAME': "PROCESSING"; /** Early hints for the client. */ EARLYHINTS: 103; '103_NAME': "EARLY_HINTS"; /** Request succeeded. */ OK: 200; '200_NAME': "OK"; /** Resource created. */ CREATED: 201; '201_NAME': "CREATED"; /** Request accepted for processing. */ ACCEPTED: 202; '202_NAME': "ACCEPTED"; /** Non-authoritative information. */ NON_AUTHORITATIVE_INFORMATION: 203; '203_NAME': "NON_AUTHORITATIVE_INFORMATION"; /** No content to send. */ NO_CONTENT: 204; '204_NAME': "NO_CONTENT"; /** Content reset. */ RESET_CONTENT: 205; '205_NAME': "RESET_CONTENT"; /** Partial content delivered. */ PARTIAL_CONTENT: 206; '206_NAME': "PARTIAL_CONTENT"; /** Multiple choices available. */ AMBIGUOUS: 300; '300_NAME': "AMBIGUOUS"; /** Resource moved permanently. */ MOVED_PERMANENTLY: 301; '301_NAME': "MOVED_PERMANENTLY"; /** Resource found at another URI. */ FOUND: 302; '302_NAME': "FOUND"; /** See other resource. */ SEE_OTHER: 303; '303_NAME': "SEE_OTHER"; /** Resource not modified. */ NOT_MODIFIED: 304; '304_NAME': "NOT_MODIFIED"; /** Temporary redirect. */ TEMPORARY_REDIRECT: 307; '307_NAME': "TEMPORARY_REDIRECT"; /** Permanent redirect. */ PERMANENT_REDIRECT: 308; '308_NAME': "PERMANENT_REDIRECT"; /** Bad request. */ BAD_REQUEST: 400; '400_NAME': "BAD_REQUEST"; /** Authentication required. */ UNAUTHORIZED: 401; '401_NAME': "UNAUTHORIZED"; /** Payment required. */ PAYMENT_REQUIRED: 402; '402_NAME': "PAYMENT_REQUIRED"; /** Access forbidden. */ FORBIDDEN: 403; '403_NAME': "FORBIDDEN"; /** Resource not found. */ NOT_FOUND: 404; '404_NAME': "NOT_FOUND"; /** Method not allowed. */ METHOD_NOT_ALLOWED: 405; '405_NAME': "METHOD_NOT_ALLOWED"; /** Not acceptable content. */ NOT_ACCEPTABLE: 406; '406_NAME': "NOT_ACCEPTABLE"; /** Proxy authentication required. */ PROXY_AUTHENTICATION_REQUIRED: 407; '407_NAME': "PROXY_AUTHENTICATION_REQUIRED"; /** Request timed out. */ REQUEST_TIMEOUT: 408; '408_NAME': "REQUEST_TIMEOUT"; /** Conflict with current state. */ CONFLICT: 409; '409_NAME': "CONFLICT"; /** Resource gone. */ GONE: 410; '410_NAME': "GONE"; /** Length required. */ LENGTH_REQUIRED: 411; '411_NAME': "LENGTH_REQUIRED"; /** Precondition failed. */ PRECONDITION_FAILED: 412; '412_NAME': "PRECONDITION_FAILED"; /** Payload too large. */ PAYLOAD_TOO_LARGE: 413; '413_NAME': "PAYLOAD_TOO_LARGE"; /** URI too long. */ URI_TOO_LONG: 414; '414_NAME': "URI_TOO_LONG"; /** Unsupported media type. */ UNSUPPORTED_MEDIA_TYPE: 415; '415_NAME': "UNSUPPORTED_MEDIA_TYPE"; /** Requested range not satisfiable. */ REQUESTED_RANGE_NOT_SATISFIABLE: 416; '416_NAME': "REQUESTED_RANGE_NOT_SATISFIABLE"; /** Expectation failed. */ EXPECTATION_FAILED: 417; '417_NAME': "EXPECTATION_FAILED"; /** I'm a teapot. */ I_AM_A_TEAPOT: 418; '418_NAME': "I_AM_A_TEAPOT"; /** Misdirected request. */ MISDIRECTED: 421; '421_NAME': "MISDIRECTED"; /** Unprocessable entity. */ UNPROCESSABLE_ENTITY: 422; '422_NAME': "UNPROCESSABLE_ENTITY"; /** Locked. */ LOCKED: 423; '423_NAME': "LOCKED"; /** Failed dependency. */ FAILED_DEPENDENCY: 424; '424_NAME': "FAILED_DEPENDENCY"; /** Too early. */ TOO_EARLY: 425; '425_NAME': "TOO_EARLY"; /** Upgrade required. */ UPGRADE_REQUIRED: 426; '426_NAME': "UPGRADE_REQUIRED"; /** Precondition required. */ PRECONDITION_REQUIRED: 428; '428_NAME': "PRECONDITION_REQUIRED"; /** Too many requests. */ TOO_MANY_REQUESTS: 429; '429_NAME': "TOO_MANY_REQUESTS"; /** Request header fields too large. */ REQUEST_HEADER_FIELDS_TOO_LARGE: 431; '431_NAME': "REQUEST_HEADER_FIELDS_TOO_LARGE"; /** Unavailable for legal reasons. */ UNAVAILABLE_FOR_LEGAL_REASONS: 451; '451_NAME': "UNAVAILABLE_FOR_LEGAL_REASONS"; /** Internal server error. */ INTERNAL_SERVER_ERROR: 500; '500_NAME': "INTERNAL_SERVER_ERROR"; /** Not implemented. */ NOT_IMPLEMENTED: 501; '501_NAME': "NOT_IMPLEMENTED"; /** Bad gateway. */ BAD_GATEWAY: 502; '502_NAME': "BAD_GATEWAY"; /** Service unavailable. */ SERVICE_UNAVAILABLE: 503; '503_NAME': "SERVICE_UNAVAILABLE"; /** Gateway timeout. */ GATEWAY_TIMEOUT: 504; '504_NAME': "GATEWAY_TIMEOUT"; /** HTTP version not supported. */ HTTP_VERSION_NOT_SUPPORTED: 505; '505_NAME': "HTTP_VERSION_NOT_SUPPORTED"; /** Variant also negotiates. */ VARIANT_ALSO_NEGOTIATES: 506; '506_NAME': "VARIANT_ALSO_NEGOTIATES"; /** Insufficient storage. */ INSUFFICIENT_STORAGE: 507; '507_NAME': "INSUFFICIENT_STORAGE"; /** Loop detected. */ LOOP_DETECTED: 508; '508_NAME': "LOOP_DETECTED"; /** Bandwidth limit exceeded. */ BANDWIDTH_LIMIT_EXCEEDED: 509; '509_NAME': "BANDWIDTH_LIMIT_EXCEEDED"; /** Not extended. */ NOT_EXTENDED: 510; '510_NAME': "NOT_EXTENDED"; /** Network authentication required. */ NETWORK_AUTHENTICATION_REQUIRED: 511; '511_NAME': "NETWORK_AUTHENTICATION_REQUIRED"; }>; //#endregion //#region src/types.d.ts /** Extracts the value type of an object */ type ValueOf<T> = T[keyof T]; /** Filters out only number types from a union */ type NumberOf<K> = Extract<K, number>; type HttpStatusCode = NumberOf<ValueOf<typeof HttpStatus>>; /** * @module * HTTP Status utility. */ type SuccessStatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226; type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308; type ServerErrorStatusCode = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511; type ClientErrorStatusCode = Exclude<HttpStatusCode, ServerErrorStatusCode | RedirectStatusCode | SuccessStatusCode>; /** * A generic type for request handler functions in an Express application. * * @example * // Example usage for a login handler * type LoginHandler = Handler<InputType<{ username: string; password: string }>>; */ type Handler<T extends InputType = any, R = any> = (req: Request<T['query'], any, T['body'], T['param']>, res: Response, next: NextFunction) => R; /** * A generic type for input validation schemas. * * @example * // Example usage for a login input schema * type LoginInput = InputType<{ username: string; password: string }>; */ type InputType<TBody = any, TParam = any, TQuery = any> = { body: TBody; query: TParam; param: TQuery; }; type Constructor<T> = new (...args: any[]) => T; type WrappedMethods<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? RequestHandler : T[K] }; //#endregion //#region src/utils.d.ts /** * Express middleware to handle `HttpError` and unknown errors. * * - Sends JSON response for `HttpError` instances. * - Logs unknown errors and sends generic error response. * - Includes detailed error info in development (`isDev`). * * @param {Boolean} [isDev = true] - Flag to indicate if the environment is development. * @param {(error: unknown) => void} [logger = console.error] - Function to log errors. * @returns {ErrorRequestHandler} - Middleware for handling errors. * * @example * // Basic usage with default options: * app.use(errorHandler(process.env.NODE_ENV !== 'production')); * // Custom usage with a logging function in production mode: * app.use(errorHandler(conf.isDev, logger.error)); */ declare const errorHandler: (isDev?: boolean, logger?: (error: unknown) => void) => ErrorRequestHandler; /** * Middleware to handle 404 Not Found errors. * * This function creates an Express router that catches all requests to * undefined routes and returns a JSON response with a 404 error. * * @param {string} [path='*'] - The route pattern to match (default: '*'). * @returns {Router} Express router instance handling 404 errors. * * @example * app.use(notFound()) */ declare const notFound: (path?: string) => Router; /** Map Action and subject with filter */ type MapObject<A extends readonly string[], S extends readonly string[], F extends Partial<Record<S[number], A[number][]>>> = Pick<{ [K in Uppercase<`${S[number]}_${A[number]}`>]: K extends `${infer Sub}_${infer Act}` ? `${Lowercase<Sub>}:${Lowercase<Act>}` : never }, Uppercase<`${Exclude<S[number], keyof F>}_${A[number]}`> | (keyof F extends infer FS ? FS extends S[number] ? F[FS] extends readonly A[number][] ? Uppercase<`${FS}_${F[FS][number]}`> : never : never : never)>; /** * Generates a permission object mapping subjects and actions to permission strings. * * @template A - List of actions that can be performed. * @template S - List of subjects (resources) being acted upon. * @template F - Optional object specifying which actions are allowed per subject. * * @param {Options<A, S, F>} options - The options object containing actions, subjects, and an optional filter. * @returns {Readonly<PermissionMapping<A, S, F>>} A frozen object mapping subjects and actions to permission strings. * * @example * const permissions = makePermission({ * actions: ['create', 'read', 'update', 'delete'] as const, * subjects: ['user', 'post', 'comment'] as const, * filter: { * user: ['read'], * post: ['create', 'update'], * }, * }); * console.log(permissions.USER_CREATE); */ declare function makePermission<A extends readonly string[], S extends readonly string[], F extends Partial<Record<S[number], A[number][]>>>(options: { actions: A; subjects: S; filter?: F; }): Readonly<MapObject<A, S, F>>; //#endregion //#region src/errors.d.ts /** The type for the body message of HTTP errors. */ type Message = string | string[]; /** The structure of the HTTP error body. */ type HttpErrorBody = { data?: Record<string, unknown> | null; code?: string | null; error: string; status: Status$1; message: Message; }; type Status$1 = ServerErrorStatusCode | ClientErrorStatusCode; /** * Get a human-readable error name from the HTTP status code. * @param {number} status - The HTTP status code. * @returns {string} - The formatted error name. */ declare const getErrorName: (status: Status$1) => string; /** * Base class for handling HTTP errors. * @extends {Error} */ declare class HttpError extends Error { readonly status: Status$1; readonly options: Pick<HttpErrorBody, 'message' | 'data' | 'code'> & { cause?: unknown; }; /** * Creates an instance of `HTTPException`. * @param status - HTTP status code for the exception. Defaults to 500. * @param options - Additional options for the exception. */ constructor(status: Status$1, options: Pick<HttpErrorBody, 'message' | 'data' | 'code'> & { cause?: unknown; }); /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ static isHttpError: (value: unknown) => value is HttpError; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ get body(): HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; } /** * Utility function to create custom error classes. * @param status - HTTP status code. * @returns - A new error class. * @example * const NotFoundError = createHttpErrorClass(HttpStatus.NOT_FOUND); */ declare const createHttpErrorClass: (status: Status$1) => { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents a Bad Request HTTP error (400). * @extends {HttpError} */ declare const BadRequestError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents a Conflict HTTP error (409). * @extends {HttpError} */ declare const ConflictError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents a Forbidden HTTP error (403). * @extends {HttpError} */ declare const ForbiddenError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents a Not Found HTTP error (404). * @extends {HttpError} */ declare const NotFoundError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents an UnAuthorized HTTP error (401). * @extends {HttpError} */ declare const UnAuthorizedError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents an Internal Server Error HTTP error (500). * @extends {HttpError} */ declare const InternalServerError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; /** * Represents an Content Too Larger Error HTTP error (413). * @extends {HttpError} */ declare const ContentTooLargeError: { new (message: Message, options?: { cause?: unknown; code?: string | null; data?: Record<string, unknown> | null; }): { readonly status: Status$1; readonly options: Pick<HttpErrorBody, "message" | "data" | "code"> & { cause?: unknown; }; /** * Convert the HttpError instance to a Body object. * @example * const errorBody = new HttpError(404, {message: 'Not Found'}).body; */ readonly body: HttpErrorBody; /** * Send the json of the error in an HTTP response. * @param {Response} res - The Express response object. * * @example * new HttpError(404, {message: 'Not Found'}).toJson(res); */ toJson(res: Response): void; name: string; message: string; stack?: string; }; /** * Check if the given error is an instance of HttpError. * @param {unknown} value - The error to check. * @returns {boolean} - True if the error is an instance of HttpError, false otherwise. * * @example * if (HttpError.isHttpError(error)) { * // Handle the HttpError * } */ isHttpError: (value: unknown) => value is HttpError; captureStackTrace(targetObject: object, constructorOpt?: Function): void; prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any; stackTraceLimit: number; }; //#endregion //#region src/api-res.d.ts type Status = Exclude<HttpStatusCode, ClientErrorStatusCode | ServerErrorStatusCode | RedirectStatusCode>; /** The structure of the HTTP response body. */ type HttpResBody = { result: any; status: number; message: string; }; /** * ApiRes class for standardizing API responses */ declare class ApiRes { readonly result: any; readonly status: Status; readonly message: string; /** * Creates an instance of ApiRes. * @param {any} result - The result of the operation * @param {Status} status - The HTTP status code * @param {string} message - The response message */ constructor(result?: any, status?: Status, message?: string); /** * Returns the Body (JSON) representation of the response. * @returns The Body (JSON) representation of the response * * @example * new ApiRes('Hello World', 200).body; */ get body(): HttpResBody; /** * Send the json of HTTP response. * @param {Response} res - The Express response object. * * @example * new ApiRes('Hello World', 200).toJson(res); */ toJson(res: Response): void; /** * Creates an OK (200) response. * @param {any} result - The result to be included in the response * @param {string} [message='Request processed successfully'] - The response message * @returns {ApiRes} An ApiRes instance with OK status */ static ok: (result: any, message?: string) => ApiRes; /** * Creates a Created (201) response. * @param {any} result - The result to be included in the response * @param {string} [message='Resource created successfully'] - The response message * @returns {ApiRes} An ApiRes instance with Created status */ static created: (result: any, message?: string) => ApiRes; /** * Creates a paginated OK (200) response. * @param {any} data - The paginated data * @param {object} meta - Metadata for pagination * @param {string} [message='Data retrieved successfully'] - The response message * @returns {ApiRes} An ApiRes instance with OK status and paginated data */ static paginated: (data: any, meta: object, message?: string) => ApiRes; } //#endregion //#region src/handler.d.ts /** * Wraps an async route handler to manage errors and response handling. * * @param {Handler} callback - The route handler, which can return a value or a Promise. * @returns {Handler} - A wrapped handler with error and result handling. * * @example * // without type * app.get('/example', handler(async () => await fetchData())); * // with body type * app.get('/example', handler<InputType<{name: string}>>(async req => await fetchData(req.body.name))); * // with param type * app.get('/example', handler<InputType<any, {name: string}>>(async req => await fetchData(req.param.name))); * // with query type * app.get('/example', handler<InputType<any, any, {name: string}>>(async req => await fetchData(req.query.name))); */ declare const handler: <I extends InputType>(callback: Handler<I, any | Promise<any>>) => Handler<I, Promise<void>>; /** * @param clsOrInstance - The class constructor or an instance of the class. * @param args - The arguments for the class constructor. * @returns A proxied instance where all methods are wrapped with `async-handler`. * * @example * class MyClass { * async myMethod() { * return 'Hello, World!'; * } * } * const instance = proxyWrapper(MyClass); * * app.get("/", instance.myMethod) */ declare const proxyWrapper: { /** * Wraps a class constructor in a Proxy, allowing all methods to be * automatically wrapped with `asyncHandler`. * * @param clsOrInstance - The class constructor. * @returns A proxied instance where all methods are wrapped with `asyncHandler`. * * @example * class MyClass { * async myMethod() { * return 'Hello, World!'; * } * } * const proxiedInstance = proxyWrapper(MyClass); * await proxiedInstance.myMethod(); // Automatically wrapped with asyncHandler */ <T extends object>(clsOrInstance: Constructor<T>): WrappedMethods<T>; /** * Wraps an instance of a class in a Proxy, allowing all methods to be * automatically wrapped with `asyncHandler`. * * @param clsOrInstance - An instance of the class. * @returns A proxied instance where all methods are wrapped with `asyncHandler`. * * @example * class MyClass { * async myMethod() { * return 'Hello, World!'; * } * } * const instance = new MyClass(); * const proxiedInstance = proxyWrapper(instance); * await proxiedInstance.myMethod(); // Automatically wrapped with asyncHandler */ <T extends object>(clsOrInstance: T): WrappedMethods<T>; /** * Wraps a class constructor in a Proxy, allowing all methods to be * automatically wrapped with `asyncHandler`, with constructor arguments. * * @param clsOrInstance - The class constructor. * @param args - The arguments for the class constructor. * @returns A proxied instance where all methods are wrapped with `asyncHandler`. * * @example * class MyClass { * constructor(private name: string) {} * async greet() { * return `Hello, ${this.name}!`; * } * } * const proxiedInstance = proxyWrapper(MyClass, 'Alice'); * await proxiedInstance.greet(); // Automatically wrapped with asyncHandler */ <T extends object>(clsOrInstance: Constructor<T>, ...args: ConstructorParameters<Constructor<T>>): WrappedMethods<T>; }; //#endregion export { ApiRes, BadRequestError, ClientErrorStatusCode, ConflictError, Constructor, ContentTooLargeError, ForbiddenError, Handler, HttpError, HttpErrorBody, HttpResBody, HttpStatus, HttpStatusCode, InputType, InternalServerError, NotFoundError, NumberOf, RedirectStatusCode, ServerErrorStatusCode, SuccessStatusCode, UnAuthorizedError, ValueOf, WrappedMethods, createHttpErrorClass, errorHandler, getErrorName, handler, makePermission, notFound, proxyWrapper };