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

57
src/Types/Handler.ts Normal file
View File

@@ -0,0 +1,57 @@
import { IContext } from '../Interfaces/mod.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`.
*/
type Handler<TContext extends IContext = IContext> = (
ctx: TContext,
) => Promise<Response>;
/**
* Represents a handler function with an associated name.
*
* This is useful for debugging, logging, or when you need to reference
* the handler by name in your application.
*
* @template TContext The specific context type for this handler, including typed `state`, `params`, and `query`.
*/
type NamedHandler<TContext extends IContext = IContext> =
& Handler<TContext>
& { name?: string };
export type { NamedHandler as Handler };
/**
* 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 Handler<TContext> {
return (
typeof value === 'function' &&
value.length === 1 // ctx
);
}

51
src/Types/Middleware.ts Normal file
View File

@@ -0,0 +1,51 @@
import { IContext } from '../Interfaces/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.
*/
type Middleware<TContext extends IContext = IContext> = (
ctx: TContext,
next: () => Promise<Response>,
) => Promise<Response>;
/**
* Represents a middleware function with an associated name.
*
* This is useful for debugging, logging, or when you need to reference
* the middleware by name in your application.
*
* @template TContext The specific context type for this middleware, including state, params, and query information.
*/
type NamedMiddleware<TContext extends IContext = IContext> =
& Middleware<TContext>
& { name?: string };
export type { NamedMiddleware as Middleware };
/**
* 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 Middleware<TContext> {
return (
typeof value === 'function' &&
value.length === 2 // ctx, next
);
}

View File

@@ -1,6 +1,8 @@
// deno-coverage-ignore-file
export type { DeepPartial } from './DeepPartial.ts';
export { isHandler } from './Handler.ts';
export type { Handler } from './Handler.ts';
export type { HttpErrorHandler } from './HttpErrorHandler.ts';
export { isHttpMethod, validHttpMethods } from './HttpMethod.ts';
export type { HttpMethod } from './HttpMethod.ts';
@@ -34,6 +36,8 @@ export {
validHttpStatusCodes,
} from './HttpStatusCode.ts';
export type { HttpStatusCode } from './HttpStatusCode.ts';
export { isMiddleware } from './Middleware.ts';
export type { Middleware } from './Middleware.ts';
export type { Params } from './Params.ts';
export type { Query } from './Query.ts';
export type { RegisterRoute } from './RegisterRoute.ts';