refactor(types): unify handler and middleware definitions

- Consolidates `Handler` and `Middleware` types under `Types` module
- Replaces `IHandler` and `IMiddleware` interfaces with typed functions
- Simplifies imports and improves code organization
- Enhances debugging with named handlers and middlewares
This commit is contained in:
2025-05-08 19:03:18 +02:00
parent 56633cd95b
commit 8235680904
10 changed files with 71 additions and 66 deletions

View File

@@ -1,50 +0,0 @@
import { IContext } from './IContext.ts';
/**
* Represents a final request handler responsible for producing an HTTP response.
*
* The handler is the terminal stage of the middleware pipeline and is responsible
* for processing the incoming request and generating the final `Response`.
*
* It receives the fully-typed request context, which includes the original request,
* parsed route parameters, query parameters, and any shared state populated by prior middleware.
*
* @template TContext The specific context type for this handler, including typed `state`, `params`, and `query`.
*/
export interface IHandler<TContext extends IContext = IContext> {
/**
* Handles the request and generates a response.
*
* @param ctx - The complete request context, including request metadata, route and query parameters,
* and mutable state populated during the middleware phase.
* @returns A `Promise` resolving to an HTTP `Response` to be sent to the client.
*/
(ctx: TContext): Promise<Response>;
}
/**
* Type guard to determine whether a given value is a valid `IHandler` function.
*
* This function checks whether the input is a function and whether it returns
* a `Promise<Response>` when called. Due to TypeScript's structural typing and
* the lack of runtime type information, only minimal runtime validation is possible.
*
* @param value - The value to test.
* @returns `true` if the value is a function that appears to conform to `IHandler`.
*
* @example
* ```ts
* const candidate = async (ctx: IContext) => new Response("ok");
* if (isHandler(candidate)) {
* // candidate is now typed as IHandler<IContext>
* }
* ```
*/
export function isHandler<TContext extends IContext = IContext>(
value: unknown,
): value is IHandler<TContext> {
return (
typeof value === 'function' &&
value.length === 1 // ctx
);
}

View File

@@ -1,6 +1,4 @@
import { HttpMethod } from '../Types/mod.ts';
import { IHandler } from './IHandler.ts';
import { IMiddleware } from './IMiddleware.ts';
import { Handler, HttpMethod, Middleware } from '../Types/mod.ts';
import { IContext, IRouteMatcher } from './mod.ts';
/**
@@ -32,10 +30,10 @@ export interface IInternalRoute<TContext extends IContext = IContext> {
/**
* An ordered list of middleware functions to be executed before the handler.
*/
middlewares: IMiddleware<TContext>[];
middlewares: Middleware<TContext>[];
/**
* The final handler that generates the HTTP response after all middleware has run.
*/
handler: IHandler<TContext>;
handler: Handler<TContext>;
}

View File

@@ -1,43 +0,0 @@
import { IContext } from './IContext.ts';
/**
* Represents a middleware function in the HTTP request pipeline.
*
* Middleware is a core mechanism to intercept, observe, or modify the request lifecycle.
* It can be used for tasks such as logging, authentication, input validation,
* metrics collection, or response transformation.
*
* Each middleware receives a fully-typed request context and a `next()` function
* to invoke the next stage of the pipeline. Middleware may choose to short-circuit
* the pipeline by returning a `Response` early.
*
* @template TContext The specific context type for this middleware, including state, params, and query information.
*/
export interface IMiddleware<TContext extends IContext = IContext> {
/**
* Handles the request processing at this middleware stage.
*
* @param ctx - The full request context, containing request, params, query, and typed state.
* @param next - A continuation function that executes the next middleware or handler in the pipeline.
* @returns A `Promise` resolving to an HTTP `Response`, either from this middleware or downstream.
*/
(ctx: TContext, next: () => Promise<Response>): Promise<Response>;
}
/**
* Type guard to verify whether a given value is a valid `IMiddleware` function.
*
* This guard checks whether the input is a function that accepts exactly two arguments.
* Note: This is a structural check and cannot fully guarantee the semantics of a middleware.
*
* @param value - The value to test.
* @returns `true` if the value is structurally a valid middleware function.
*/
export function isMiddleware<TContext extends IContext = IContext>(
value: unknown,
): value is IMiddleware<TContext> {
return (
typeof value === 'function' &&
value.length === 2 // ctx, next
);
}

View File

@@ -1,6 +1,5 @@
import { IHandler } from './IHandler.ts';
import { Handler, Middleware } from '../Types/mod.ts';
import { IInternalRoute } from './IInternalRoute.ts';
import { IMiddleware } from './IMiddleware.ts';
import { IRouteDefinition } from './IRouteDefinition.ts';
import { IContext } from './mod.ts';
@@ -8,7 +7,7 @@ export interface IRouteBuilderFactory<TContext extends IContext = IContext> {
new (
registerRoute: (route: IInternalRoute<TContext>) => void,
def: IRouteDefinition,
mws?: IMiddleware<TContext>[],
mws?: Middleware<TContext>[],
): IRouteBuilder<TContext>;
}
@@ -25,7 +24,7 @@ export interface IRouteBuilder<TContext extends IContext = IContext> {
* @returns The route builder for further chaining.
*/
middleware(
mw: IMiddleware<TContext>,
mw: Middleware<TContext>,
): IRouteBuilder<TContext>;
/**
@@ -35,6 +34,6 @@ export interface IRouteBuilder<TContext extends IContext = IContext> {
* @param handler - The function to execute when this route is matched.
*/
handle(
handler: IHandler<TContext>,
handler: Handler<TContext>,
): void;
}

View File

@@ -1,14 +1,10 @@
// deno-coverage-ignore-file
export type { IContext } from './IContext.ts';
export { isHandler } from './IHandler.ts';
export type { IHandler } from './IHandler.ts';
export type { IHttpErrorHandlers } from './IHttpErrorHandlers.ts';
export type { IHttpKernel } from './IHttpKernel.ts';
export type { IHttpKernelConfig } from './IHttpKernelConfig.ts';
export type { IInternalRoute } from './IInternalRoute.ts';
export { isMiddleware } from './IMiddleware.ts';
export type { IMiddleware } from './IMiddleware.ts';
export type { IRouteBuilder, IRouteBuilderFactory } from './IRouteBuilder.ts';
export {
isDynamicRouteDefinition,