First commit

Signed-off-by: Max P. <Mail@MPassarello.de>
This commit is contained in:
2025-05-07 10:53:56 +02:00
commit 1d2e89feca
20 changed files with 919 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
/**
* Represents the per-request context passed through the middleware pipeline and to the final handler.
*
* This context object encapsulates the original HTTP request,
* the path parameters extracted from the matched route,
* and a mutable state object for sharing information across middlewares and handlers.
*/
export interface IContext {
/**
* The original HTTP request object as received by Deno.
* Contains all standard fields like headers, method, body, etc.
*/
req: Request;
/**
* Route parameters parsed from the URL path, based on route definitions
* that include dynamic segments (e.g., `/users/:id` → `{ id: "123" }`).
*
* These parameters are considered read-only and are set by the router.
*/
params: Record<string, string>;
/**
* A shared, mutable object used to pass arbitrary data between middlewares and handlers.
*
* Use this field to attach validated user info, auth state, logging context, etc.
*
* Each key should be well-named to avoid collisions across layers.
*/
state: Record<string, unknown>;
}

View File

@@ -0,0 +1,16 @@
import { IContext } from './IContext.ts';
/**
* Represents a final request handler responsible for generating a response.
*
* The handler is the last step in the middleware pipeline and must return
* a valid HTTP `Response`. It has access to all data injected into the
* request context, including path parameters and any state added by middleware.
*/
export interface IHandler {
/**
* @param ctx - The complete request context, including parameters and middleware state.
* @returns A promise resolving to an HTTP `Response`.
*/
(ctx: IContext): Promise<Response>;
}

View File

@@ -0,0 +1,33 @@
import { IRouteBuilder } from './IRouteBuilder.ts';
import { IRouteDefinition } from './IRouteDefinition.ts';
/**
* Defines the core interface for the HTTP kernel, responsible for route registration,
* middleware orchestration, and request dispatching.
*/
export interface IHttpKernel {
/**
* Registers a new route with a static path pattern or a dynamic matcher.
*
* This method accepts both conventional route definitions (with path templates)
* and advanced matcher-based routes for flexible URL structures.
*
* Returns a route builder that allows chaining middleware and assigning a handler.
*
* @param definition - A static or dynamic route definition, including the HTTP method
* and either a path pattern or custom matcher function.
* @returns A builder interface to attach middleware and define the handler.
*/
route(definition: IRouteDefinition): IRouteBuilder;
/**
* Handles an incoming HTTP request by matching it against registered routes,
* executing any associated middleware in order, and invoking the final route handler.
*
* This method serves as the main entry point to integrate with `Deno.serve`.
*
* @param request - The incoming HTTP request object.
* @returns A promise resolving to the final HTTP response.
*/
handle(request: Request): Promise<Response>;
}

View File

@@ -0,0 +1,42 @@
import { IHandler } from './IHandler.ts';
import { IMiddleware } from './IMiddleware.ts';
/**
* Represents an internally registered route within the HttpKernel.
*
* Contains all data required to match an incoming request and dispatch it
* through the associated middleware chain and final handler.
*/
export interface IInternalRoute {
/**
* The HTTP method (e.g. 'GET', 'POST') that this route responds to.
* The method should always be in uppercase.
*/
method: string;
/**
* A matcher function used to determine whether this route matches a given request.
*
* If the matcher returns `null`, the route does not apply to the request.
* If it returns a params object, the route is considered matched and the extracted
* parameters are passed into the request context.
*
* @param url - The parsed URL object from the incoming request.
* @param req - The original Request object.
* @returns An object with extracted path parameters, or `null` if not matched.
*/
matcher: (
url: URL,
req: Request,
) => null | { params: Record<string, string> };
/**
* An ordered list of middleware functions to be executed before the handler.
*/
middlewares: IMiddleware[];
/**
* The final handler that generates the HTTP response after all middleware has run.
*/
handler: IHandler;
}

View File

@@ -0,0 +1,20 @@
import { IContext } from './IContext.ts';
/**
* Represents a middleware function in the HTTP request pipeline.
*
* Middleware can perform tasks such as logging, authentication, validation,
* or response transformation. It receives the current request context and
* a `next()` function to delegate control to the next middleware or final handler.
*
* To stop the request pipeline, a middleware can return a `Response` directly
* without calling `next()`.
*/
export interface IMiddleware {
/**
* @param ctx - The request context, containing the request, path parameters, and shared state.
* @param next - A function that continues the middleware pipeline. Returns the final `Response`.
* @returns A promise resolving to an HTTP `Response`.
*/
(ctx: IContext, next: () => Promise<Response>): Promise<Response>;
}

View File

@@ -0,0 +1,35 @@
import { IHandler } from './IHandler.ts';
import { IInternalRoute } from './IInternalRoute.ts';
import { IMiddleware } from './IMiddleware.ts';
import { IRouteDefinition } from './IRouteDefinition.ts';
export interface IRouteBuilderFactory {
new (
registerRoute: (route: IInternalRoute) => void,
def: IRouteDefinition,
mws?: IMiddleware[],
): IRouteBuilder;
}
/**
* Provides a fluent API to build a single route configuration by chaining
* middleware and setting the final request handler.
*/
export interface IRouteBuilder {
/**
* Adds a middleware to the current route.
* Middleware will be executed in the order of registration.
*
* @param mw - A middleware function.
* @returns The route builder for further chaining.
*/
middleware(mw: IMiddleware): IRouteBuilder;
/**
* Sets the final request handler for the route.
* Calling this finalizes the route and registers it in the kernel.
*
* @param handler - The function to execute when this route is matched.
*/
handle(handler: IHandler): void;
}

View File

@@ -0,0 +1,46 @@
import { IRouteMatcher } from './IRouteMatcher.ts';
/**
* Defines a static route using a path pattern with optional parameters.
*
* Suitable for conventional routes like "/users/:id", which can be parsed
* into named parameters using a path-matching library.
*/
export interface IStaticRouteDefinition {
/**
* The HTTP method this route should match (e.g. "GET", "POST").
*/
method: string;
/**
* A static path pattern for the route, which may include named parameters
* (e.g. "/caches/:id"). Internally, this can be converted to a regex matcher.
*/
path: string;
}
/**
* Defines a dynamic route using a custom matcher function instead of a static path.
*
* Useful for complex URL structures that cannot easily be expressed using a static pattern,
* such as routes with variable prefixes or conditional segment logic.
*/
export interface IDynamicRouteDefinition {
/**
* The HTTP method this route should match (e.g. "GET", "POST").
*/
method: string;
/**
* A custom matcher function that receives the parsed URL and raw request.
* If the function returns `null`, the route does not match.
* If the function returns a params object, the route is considered matched.
*/
matcher: IRouteMatcher;
}
/**
* A route definition can either be a conventional static route with a path pattern,
* or a dynamic route with a custom matcher function for advanced matching logic.
*/
export type IRouteDefinition = IStaticRouteDefinition | IDynamicRouteDefinition;

View File

@@ -0,0 +1,34 @@
import { IRouteDefinition } from './IRouteDefinition.ts';
/**
* Defines a route matcher function that evaluates whether a route applies to a given request.
*
* If the route matches, the matcher returns an object containing extracted route parameters.
* Otherwise, it returns `null`.
*/
export interface IRouteMatcher {
/**
* Evaluates whether the given URL and request match a defined route.
*
* @param url - The full URL of the incoming request.
* @param req - The raw Request object (may be used for context or headers).
* @returns An object containing path parameters if matched, or `null` if not matched.
*/
(url: URL, req: Request): null | { params: Record<string, string> };
}
/**
* Represents a factory for creating route matcher functions from route definitions.
*
* This allows the matcher logic to be injected or replaced (e.g. for testing,
* pattern libraries, or advanced routing scenarios).
*/
export interface IRouteMatcherFactory {
/**
* Creates a matcher function based on a given route definition.
*
* @param def - The route definition (static or dynamic).
* @returns A matcher function that checks if a request matches and extracts parameters.
*/
(def: IRouteDefinition): IRouteMatcher;
}

View File

@@ -0,0 +1,25 @@
/**
* A function that modifies or enriches an outgoing HTTP response before it is returned to the client.
*
* This decorator can be used to inject headers (e.g., CORS, security), apply global transformations,
* or wrap responses for logging, analytics, or debugging purposes.
*
* It is called exactly once at the end of the middleware/handler pipeline,
* allowing central response customization without interfering with business logic.
*
* @param res - The original `Response` object produced by the route handler or middleware chain.
* @returns A modified or wrapped `Response` object to be sent back to the client.
*
* @example
* ```ts
* const addCors: ResponseDecorator = (res) => {
* const headers = new Headers(res.headers);
* headers.set("Access-Control-Allow-Origin", "*");
* return new Response(res.body, {
* status: res.status,
* headers,
* });
* };
* ```
*/
export type ResponseDecorator = (res: Response) => Response;

13
src/Interfaces/mod.ts Normal file
View File

@@ -0,0 +1,13 @@
export type { IContext } from './IContext.ts';
export type { IMiddleware } from './IMiddleware.ts';
export type { IHandler } from './IHandler.ts';
export type { IHttpKernel } from './IHttpKernel.ts';
export type { IRouteBuilder, IRouteBuilderFactory } from './IRouteBuilder.ts';
export type {
IDynamicRouteDefinition,
IRouteDefinition,
IStaticRouteDefinition,
} from './IRouteDefinition.ts';
export type { IInternalRoute } from './IInternalRoute.ts';
export type { IRouteMatcher } from './IRouteMatcher.ts';
export type { ResponseDecorator } from './ResponseDecorator.ts';