import { Middleware } from "./middleware.cjs";
import { Endpoint, EndpointOptions } from "./endpoint.cjs";

//#region src/router.d.ts
interface RouterConfig {
  throwError?: boolean;
  onError?: (e: unknown) => void | Promise<void> | Response | Promise<Response>;
  basePath?: string;
  routerMiddleware?: Array<{
    path: string;
    middleware: Middleware;
  }>;
  /**
   * additional Context that needs to passed to endpoints
   *
   * this will be available on `ctx.context` on endpoints
   */
  routerContext?: Record<string, any>;
  /**
   * A callback to run before any response
   */
  onResponse?: (res: Response) => any | Promise<any>;
  /**
   * A callback to run before any request
   */
  onRequest?: (req: Request) => any | Promise<any>;
  /**
   * List of allowed media types (MIME types) for the router
   *
   * if provided, only the media types in the list will be allowed to be passed in the body.
   *
   * If an endpoint has allowed media types, it will override the router's allowed media types.
   *
   * @example
   * ```ts
   * const router = createRouter({
   * 		allowedMediaTypes: ["application/json", "application/x-www-form-urlencoded"],
   * 	})
   */
  allowedMediaTypes?: string[];
  /**
   * Skip trailing slashes
   *
   * @default false
   */
  skipTrailingSlashes?: boolean;
  /**
   * Open API route configuration
   */
  openapi?: {
    /**
     * Disable openapi route
     *
     * @default false
     */
    disabled?: boolean;
    /**
     * A path to display open api using scalar
     *
     * @default "/api/reference"
     */
    path?: string;
    /**
     * Scalar Configuration
     */
    scalar?: {
      /**
       * Title
       * @default "Open API Reference"
       */
      title?: string;
      /**
       * Description
       *
       * @default "Better Call Open API Reference"
       */
      description?: string;
      /**
       * Logo URL
       */
      logo?: string;
      /**
       * Scalar theme
       * @default "saturn"
       */
      theme?: string;
    };
  };
}
declare const createRouter: <E extends Record<string, Endpoint>, Config extends RouterConfig>(endpoints: E, config?: Config) => {
  handler: (request: Request) => Promise<Response>;
  endpoints: E;
  /**
   * Add a new endpoint to the router.
   * This is useful if you want to add an endpoint to the router after it has been created.
   */
  addEndpoint: (endpoint: Endpoint) => void;
  /**
   * Find a route in the router.
   * @param method - The HTTP method of the route.
   * @param path - The path of the route.
   * @returns The route data and parameters.
   */
  findRoute: (method: string, path: string) => {
    data: Endpoint & {
      path: string;
    };
    params: Record<string, string>;
  };
  /**
   * Extend the router with new endpoints
   * @param newEndpoints new endpoints to extend the router with
   * @returns new router with additional endpoints
   */
  extend: <NE extends Record<string, Endpoint>>(newEndpoints: NE) => {
    handler: (request: Request) => Promise<Response>;
    endpoints: E & NE;
    /**
     * Add a new endpoint to the router.
     * This is useful if you want to add an endpoint to the router after it has been created.
     */
    addEndpoint: (endpoint: Endpoint) => void;
    /**
     * Find a route in the router.
     * @param method - The HTTP method of the route.
     * @param path - The path of the route.
     * @returns The route data and parameters.
     */
    findRoute: (method: string, path: string) => {
      data: ((inputCtx: any) => Promise<any>) & {
        options: EndpointOptions;
        path: string;
      } & {
        path: string;
      };
      params: Record<string, string>;
    };
    extend: <NE_1 extends Record<string, Endpoint>>(newEndpoints: NE_1) => {
      handler: (request: Request) => Promise<Response>;
      endpoints: E & NE & NE_1;
      /**
       * Add a new endpoint to the router.
       * This is useful if you want to add an endpoint to the router after it has been created.
       */
      addEndpoint: (endpoint: Endpoint) => void;
      /**
       * Find a route in the router.
       * @param method - The HTTP method of the route.
       * @param path - The path of the route.
       * @returns The route data and parameters.
       */
      findRoute: (method: string, path: string) => {
        data: ((inputCtx: any) => Promise<any>) & {
          options: EndpointOptions;
          path: string;
        } & {
          path: string;
        };
        params: Record<string, string>;
      };
      extend: <NE_2 extends Record<string, Endpoint>>(newEndpoints: NE_2) => {
        handler: (request: Request) => Promise<Response>;
        endpoints: E & NE & NE_1 & NE_2;
        /**
         * Add a new endpoint to the router.
         * This is useful if you want to add an endpoint to the router after it has been created.
         */
        addEndpoint: (endpoint: Endpoint) => void;
        /**
         * Find a route in the router.
         * @param method - The HTTP method of the route.
         * @param path - The path of the route.
         * @returns The route data and parameters.
         */
        findRoute: (method: string, path: string) => {
          data: ((inputCtx: any) => Promise<any>) & {
            options: EndpointOptions;
            path: string;
          } & {
            path: string;
          };
          params: Record<string, string>;
        };
        extend: <NE_3 extends Record<string, Endpoint>>(newEndpoints: NE_3) => {
          handler: (request: Request) => Promise<Response>;
          endpoints: E & NE & NE_1 & NE_2 & NE_3;
          /**
           * Add a new endpoint to the router.
           * This is useful if you want to add an endpoint to the router after it has been created.
           */
          addEndpoint: (endpoint: Endpoint) => void;
          /**
           * Find a route in the router.
           * @param method - The HTTP method of the route.
           * @param path - The path of the route.
           * @returns The route data and parameters.
           */
          findRoute: (method: string, path: string) => {
            data: ((inputCtx: any) => Promise<any>) & {
              options: EndpointOptions;
              path: string;
            } & {
              path: string;
            };
            params: Record<string, string>;
          };
          extend: <NE_4 extends Record<string, Endpoint>>(newEndpoints: NE_4) => {
            handler: (request: Request) => Promise<Response>;
            endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4;
            /**
             * Add a new endpoint to the router.
             * This is useful if you want to add an endpoint to the router after it has been created.
             */
            addEndpoint: (endpoint: Endpoint) => void;
            /**
             * Find a route in the router.
             * @param method - The HTTP method of the route.
             * @param path - The path of the route.
             * @returns The route data and parameters.
             */
            findRoute: (method: string, path: string) => {
              data: ((inputCtx: any) => Promise<any>) & {
                options: EndpointOptions;
                path: string;
              } & {
                path: string;
              };
              params: Record<string, string>;
            };
            extend: <NE_5 extends Record<string, Endpoint>>(newEndpoints: NE_5) => {
              handler: (request: Request) => Promise<Response>;
              endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5;
              /**
               * Add a new endpoint to the router.
               * This is useful if you want to add an endpoint to the router after it has been created.
               */
              addEndpoint: (endpoint: Endpoint) => void;
              /**
               * Find a route in the router.
               * @param method - The HTTP method of the route.
               * @param path - The path of the route.
               * @returns The route data and parameters.
               */
              findRoute: (method: string, path: string) => {
                data: ((inputCtx: any) => Promise<any>) & {
                  options: EndpointOptions;
                  path: string;
                } & {
                  path: string;
                };
                params: Record<string, string>;
              };
              extend: <NE_6 extends Record<string, Endpoint>>(newEndpoints: NE_6) => {
                handler: (request: Request) => Promise<Response>;
                endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6;
                /**
                 * Add a new endpoint to the router.
                 * This is useful if you want to add an endpoint to the router after it has been created.
                 */
                addEndpoint: (endpoint: Endpoint) => void;
                /**
                 * Find a route in the router.
                 * @param method - The HTTP method of the route.
                 * @param path - The path of the route.
                 * @returns The route data and parameters.
                 */
                findRoute: (method: string, path: string) => {
                  data: ((inputCtx: any) => Promise<any>) & {
                    options: EndpointOptions;
                    path: string;
                  } & {
                    path: string;
                  };
                  params: Record<string, string>;
                };
                extend: <NE_7 extends Record<string, Endpoint>>(newEndpoints: NE_7) => {
                  handler: (request: Request) => Promise<Response>;
                  endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7;
                  /**
                   * Add a new endpoint to the router.
                   * This is useful if you want to add an endpoint to the router after it has been created.
                   */
                  addEndpoint: (endpoint: Endpoint) => void;
                  /**
                   * Find a route in the router.
                   * @param method - The HTTP method of the route.
                   * @param path - The path of the route.
                   * @returns The route data and parameters.
                   */
                  findRoute: (method: string, path: string) => {
                    data: ((inputCtx: any) => Promise<any>) & {
                      options: EndpointOptions;
                      path: string;
                    } & {
                      path: string;
                    };
                    params: Record<string, string>;
                  };
                  extend: <NE_8 extends Record<string, Endpoint>>(newEndpoints: NE_8) => {
                    handler: (request: Request) => Promise<Response>;
                    endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8;
                    /**
                     * Add a new endpoint to the router.
                     * This is useful if you want to add an endpoint to the router after it has been created.
                     */
                    addEndpoint: (endpoint: Endpoint) => void;
                    /**
                     * Find a route in the router.
                     * @param method - The HTTP method of the route.
                     * @param path - The path of the route.
                     * @returns The route data and parameters.
                     */
                    findRoute: (method: string, path: string) => {
                      data: ((inputCtx: any) => Promise<any>) & {
                        options: EndpointOptions;
                        path: string;
                      } & {
                        path: string;
                      };
                      params: Record<string, string>;
                    };
                    extend: <NE_9 extends Record<string, Endpoint>>(newEndpoints: NE_9) => {
                      handler: (request: Request) => Promise<Response>;
                      endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8 & NE_9;
                      /**
                       * Add a new endpoint to the router.
                       * This is useful if you want to add an endpoint to the router after it has been created.
                       */
                      addEndpoint: (endpoint: Endpoint) => void;
                      /**
                       * Find a route in the router.
                       * @param method - The HTTP method of the route.
                       * @param path - The path of the route.
                       * @returns The route data and parameters.
                       */
                      findRoute: (method: string, path: string) => {
                        data: ((inputCtx: any) => Promise<any>) & {
                          options: EndpointOptions;
                          path: string;
                        } & {
                          path: string;
                        };
                        params: Record<string, string>;
                      };
                      extend: <NE_10 extends Record<string, Endpoint>>(newEndpoints: NE_10) => /*elided*/any;
                    };
                  };
                };
              };
            };
          };
        };
      };
    };
  };
};
type Router = ReturnType<typeof createRouter>;
//#endregion
export { Router, RouterConfig, createRouter };
//# sourceMappingURL=router.d.cts.map