import { Response } from "./Response.mjs"; import { Route } from "../Route.mjs"; import { ApiResourceMiddleware, HttpMethod, ResourceAction, RouteGroupContext, RouteGroupSource, RouterConfig } from "../types/basic.mjs"; import { Request } from "./Request.mjs"; import { Container } from "./bindings.mjs"; import { ClearRouterPluginArgumentsContext, ClearRouterPluginInput, ClearRouterPluginRequestContext, PluginArgumentsResolver, PluginBind } from "./plugins.mjs"; import { Controller } from "../Controller.mjs"; import { ResourceRoutes } from "../ResourceRoutes.mjs"; import { RouteGroup } from "../RouteGroup.mjs"; import { RouteRegistrar } from "../RouteRegistrar.mjs"; import { AsyncLocalStorage } from "node:async_hooks"; //#region src/core/CoreRouter.d.ts /** * @class clear-router CoreRouter * @description Core routing logic for clear-router, shared between all supported adapters (Express.js, H3, etc.) * @author 3m1n3nc3 * @repository https://github.com/arkstack-hq/clear-router */ declare abstract class CoreRouter { protected static routerStateNamespace: string; private static readonly stateStoreKey; private static readonly stateBoundKey; private static readonly defaultConfigKey; private static requestProvider?; private static responseProvider?; private static readonly domainMatcherCache; private static readonly constraintRegexCache; static routePatterns: Map; static config: RouterConfig; static container: Container; protected static groupContext: AsyncLocalStorage; protected static pluginRequestContext: AsyncLocalStorage>; static routes: Set>; static routesByPathMethod: Map>; static routesByMethod: Map<"GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD", Route[]>; static routesByName: Map>; static prefix: string; static groupMiddlewares: any[]; static globalMiddlewares: any[]; /** * Resolve middlewares before assigning to adapter * * @param middleware * @returns */ protected static resolveMiddleware(middleware: any): any; protected static resolveMiddlewares(middlewares?: any[]): any[]; protected static routeSpecificity(route: Route): [number, number, number]; protected static orderedRoutes(): Array>; protected static removeRouteMethod(route: Route, method: HttpMethod, path: string): void; protected static removeRoute(route: Route): void; /** * Resets the router to it's default state */ static reset(): typeof CoreRouter; protected static createBaseConfig(): RouterConfig; protected static mergeConfig(target: RouterConfig, source?: RouterConfig): RouterConfig; protected static getDefaultConfig(): RouterConfig; protected static resolveStateNamespace(): string; protected static getStateStore(): Record; protected static getPluginStore(): Set; protected static getPluginPendingStore(): Set>; protected static getPluginArgumentResolvers(): Set; protected static getPluginHttpCtxResolvers(): Set; protected static createDefaultState(): { config: RouterConfig; groupContext: AsyncLocalStorage; routes: Set; routesByPathMethod: Map; routesByMethod: Map; routesByName: Map; prefix: string; groupMiddlewares: any[]; globalMiddlewares: any[]; container: Container; pluginStore: Set; pluginPending: Set>; pluginArgumentResolvers: Set; pluginHttpCtxResolvers: Set; }; protected static bindStateAccessors(): void; protected static createDefaultOptionsHandler(): any; /** * Default configuration used for everytime the router is reset * * @param options */ static configureDefaults(options?: RouterConfig): void; /** * Use a registered plugin * * @param this * @param plugin * @param options * @returns */ static use(plugin: ClearRouterPluginInput, options?: Options): Promise; protected static pluginsReady(): Promise; protected static getCurrentPluginRequestContext(): ClearRouterPluginRequestContext | undefined; protected static createPluginRequestContext(ctx: any): ClearRouterPluginRequestContext; protected static createPluginBind(): PluginBind; protected static resolvePluginArguments(ctx: any, routeContext: Omit): Promise; protected static resolvePluginHttpCtx(ctx: any): Promise; protected static ensureState(): void; /** * Normalizes a path by ensuring it starts with a single slash and does not have trailing * slashes, while preserving dynamic segments and parameters. * * @param path The path to normalize. * @returns The normalized path. */ static normalizePath(path: string): string; protected static parseRouteParameters(path: string): Array<{ name: string; field?: string; optional: boolean; }>; protected static expandRoutePath(path: string): string[]; protected static routeRegistrationPaths(path: string): string[]; /** * Compile a host pattern such as `{account}.example.com` into a matcher and * the ordered list of placeholder names it captures. Results are memoized. * * @param pattern * @returns */ protected static compileDomain(pattern: string): { regex: RegExp; params: string[]; }; /** * Match a host against a domain pattern, returning the captured parameters or * `null` when the host does not match. * * @param pattern * @param host * @returns */ static matchDomain(pattern: string, host?: string | null): Record | null; /** * Best-effort extraction of the request host across every supported adapter * context shape (Express/Fastify plain headers, H3 `Headers`, Hono accessor, * Koa context). * * @param ctx * @returns */ protected static extractHost(ctx: any): string; /** * Resolve the domain parameters for a route given the active request context. * Returns `null` when the route is not domain-constrained, `false` when it is * but the host does not match, or the captured parameters on a match. * * @param route * @param ctx * @returns */ protected static matchRouteDomain(route: Route, ctx: any): Record | null | false; /** * Register a global pattern applied to every route parameter sharing the * given name (equivalent to Laravel's `Route::pattern`). * * @param name * @param pattern */ static pattern(name: string, pattern: string | RegExp): void; /** * Register multiple global parameter patterns at once. * * @param patterns */ static patterns(patterns: Record): void; /** * Merge the global parameter patterns with the route's own constraints. Route * level constraints take precedence over global patterns. * * @param route * @returns */ protected static resolveConstraints(route: Route): Record; /** * Compile a constraint pattern into a fully-anchored regular expression. * * @param pattern * @returns */ protected static toConstraintRegex(pattern: string | RegExp): RegExp; /** * Determine whether the resolved parameters satisfy the route's constraints. * Absent parameters (e.g. optional ones) are ignored. * * @param route * @param params * @returns */ protected static satisfiesConstraints(route: Route, params: Record): boolean; /** * Determine which of a route's parameters are allowed to span multiple path * segments (i.e. their constraint matches an encoded forward slash). These are * registered with the adapter's catch-all syntax. * * @param route * @returns */ protected static wildcardParameters(route: Route): Set; /** * Render a single wildcard (slash-spanning) parameter for the underlying * router's registration path. Overridden per adapter; the base form keeps the * plain `:name` placeholder. * * @param name * @returns */ protected static formatWildcardParam(name: string): string; /** * Rewrite a route's registration paths so any wildcard parameters use the * adapter's catch-all syntax. Non-wildcard routes are returned unchanged. * * @param route * @returns */ protected static resolveRegistrationPaths(route: Route): string[]; /** * Resolve the final parameters for a dispatched route, applying domain * matching and constraint validation. Returns the merged parameters, or * `false` when the route should not handle the request (host mismatch or a * constraint failure) so the adapter can fall through. * * @param route * @param ctx * @param baseParams * @returns */ protected static matchRoute(route: Route, ctx: any, baseParams?: Record): Record | false; /** * Normalize wildcard (slash-spanning) parameters into a single string keyed by * the declared parameter name, smoothing over the differing shapes adapters * return (Express yields an array of segments, Fastify keys it under `*`). * * @param route * @param params */ protected static normalizeWildcardParams(route: Route, params: Record): void; /** * Get the route currently being dispatched, if any. * * @returns */ static current(): Route | undefined; /** * Get the name of the route currently being dispatched. * * @returns */ static currentRouteName(): string; /** * Get the action (`Controller@method` or `Closure`) of the route currently * being dispatched. * * @returns */ static currentRouteAction(): string; /** * Configures the router with the given options, such as method override settings. * * @param this * @param options * @returns */ static configure(this: any, options?: RouterConfig): void; protected static resolveMethodOverride(method: string, headers: Headers | Record, body: unknown): HttpMethod | null; /** * Adds a new route to the router. * * @param this * @param methods * @param path * @param handler * @param middlewares */ static add(methods: HttpMethod | HttpMethod[], path: string, handler: any, middlewares?: any[] | any): Route; /** * Define a resourceful API controller with standard CRUD routes. * * @param this * @param basePath * @param controller * @param options */ static apiResource(basePath: string, controller: any, options?: { only?: ResourceAction[]; except?: ResourceAction[]; middlewares?: ApiResourceMiddleware; }): ResourceRoutes; /** * Adds a new GET route to the router. * * @param this The router instance. * @param path The path for the GET route. * @param handler The handler function for the GET route. * @param middlewares Optional middlewares to apply to the GET route. */ static get(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new POST route to the router. * * @param this * @param path * @param handler * @param middlewares */ static post(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new PUT route to the router. * * @param this * @param path * @param handler * @param middlewares */ static put(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new DELETE route to the router. * * @param this * @param path * @param handler * @param middlewares */ static delete(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new PATCH route to the router. * * @param this * @param path * @param handler * @param middlewares */ static patch(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new OPTIONS route to the router. * * @param this * @param path * @param handler * @param middlewares */ static options(path: string, handler: any, middlewares?: any[] | any): Route; /** * Adds a new HEAD route to the router. * * @param this * @param path * @param handler * @param middlewares */ static head(path: string, handler: any, middlewares?: any[] | any): Route; /** * Defines a group of routes with a common prefix. * * @param this * @param prefix * @param callback * @param middlewares */ static group(prefix: string, source: S, middlewares?: any[]): RouteGroup; /** * Build a route group, optionally constrained to a host pattern. Shared by * `group` and the `domain` registrar. * * @param prefix * @param source * @param middlewares * @param extra */ protected static makeGroup(prefix: string, source: S, middlewares?: any[], extra?: { domain?: string; }): RouteGroup; /** * Begin a route registration constrained to a host pattern such as * `{account}.example.com`. Returns a registrar whose `.group()` registers the * routes under that domain (matched parameters become route parameters). * * @param pattern * @returns */ static domain(pattern: string): RouteRegistrar; /** * Adds global middlewares to the router, which will be applied to all routes. * * @param this * @param middlewares * @param callback */ static middleware(middlewares: any[], callback: () => void): void; /** * Retrieves all registered routes in the router, optionally organized by path or method * for easier access and management. * * @param this */ static allRoutes(): Array>; /** * @param this * @param type - 'path' to get routes organized by path */ static allRoutes(type: 'path'): Record>; /** * @param this * @param type - 'method' to get routes organized by method */ static allRoutes(type: 'method'): { [method in Uppercase]?: Array> }; static allRoutes(type: 'name'): Record>; static route(name: string): Route | undefined; static url(name: string, params?: Record): string | undefined; /** * Provide a class that will overide the base Request instance * * @param provider */ static setRequestProvider(provider: typeof Request): void; /** * Provide a class that will overide the base Response instance * * @param provider */ static setResponseProvider(provider: typeof Response): void; private static hasPackageInstalled; /** * Provide a class that will overide the base Response instance * * @param provider */ private static initializeInstance; protected static resolveHandler(route: Route): { handlerFunction: ((ctx: any, req: Request) => any | Promise) | null; instance: Controller | null; bindingTarget?: object; bindingMethod?: PropertyKey; bindingHandler?: object; bindingMetadata?: object; }; protected static callHandler(handlerFunction: (ctx: any, req: Request) => any | Promise, ctx: any, bindingTarget?: object, bindingMethod?: PropertyKey, bindingHandler?: object, bindingMetadata?: object): Promise; protected static bindRequestToInstance(ctx: any, instance: Controller | Route | null, route: Route, payload: { body: Record; query: Record; params: Record; method?: HttpMethod | string; }): void; } //#endregion export { CoreRouter };