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 };