UNPKG

exstack

Version:

A utility library designed to simplify and enhance Express.js applications.

174 lines (172 loc) 4.64 kB
import { HttpStatus } from "./status.js"; import { NextFunction, Request, Response } from "express"; //#region src/types.d.ts /** * Extracts the union of all value types of a given object type. * * @example * ```ts * type Example = { a: 1; b: 'x'; c: true }; * type Values = ValueOf<Example>; // 1 | 'x' | true * ``` */ type ValueOf<T> = T[keyof T]; /** * Filters a union to only include numeric members. * * @example * ```ts * type Mixed = string | number | boolean; * type OnlyNumbers = NumberOf<Mixed>; // number * ``` */ type NumberOf<K> = Extract<K, number>; /** * Represents a standard Express-style route handler. * * @remarks * The handler may return: * - a plain value (string, object, etc.) * - an instance of {@link ApiRes} * - a `Promise` resolving to one of those values. * * The framework will automatically detect and send the result. */ type Handler = (req: Request, res: Response, next: NextFunction) => any | Promise<any>; /** * Extracts numeric status codes from {@link HttpStatus}. * * Ensures that only numeric HTTP status codes are allowed. */ type HttpStatusCode = NumberOf<ValueOf<typeof HttpStatus>>; /** * @module * HTTP Status Utility Types */ /** 1xx & 2xx Success Codes */ type SuccessStatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226; /** 3xx Redirect Codes */ type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308; /** 5xx Server Error Codes */ type ServerErrorStatusCode = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511; /** * 4xx Client Error Codes * * Calculated by excluding all known success, redirect, and server error codes. */ type ClientErrorStatusCode = Exclude<HttpStatusCode, SuccessStatusCode | RedirectStatusCode | ServerErrorStatusCode>; /** * Represents a single route definition. * * @template T - The type of the route handler (defaults to {@link Handler}). * * @example * ```ts * const route: RouterRoute = { * basePath: '/api', * path: '/users/:id', * method: 'get', * handler: getUserHandler, * }; * ``` */ interface RouterRoute<T = Handler> { /** Base path prefix (e.g., `/api`). */ basePath: string; /** The route pattern (e.g., `/users/:id`). */ path: string; /** The HTTP method for this route (e.g., `'get'`, `'post'`). */ method: string; /** The request handler function. */ handler: T; } /** * Defines the structure of a router that can register and match routes. * * @template T - The type of handler used in routes. * * @example * ```ts * const router: Router<Handler> = { * name: 'apiRouter', * add(method, path, handler) { * // store route * }, * match(method, path) { * // return matching route * }, * }; * ``` */ interface Router$1<T = Handler> { /** Router name (useful for debugging). */ name: string; /** * Registers a new route. * * @param method - HTTP method (e.g., `'get'`, `'post'`). * @param path - Route pattern (e.g., `'/users/:id'`). * @param handler - The route handler. */ add(method: string, path: string, handler: T): void; /** * Finds the best route match for a given HTTP method and path. * * @param method - The HTTP method. * @param path - The incoming request path. * @returns A {@link Result} describing the matched handlers and params. */ match(method: string, path: string): Result<T>; } /** * Maps route parameter names to their position indices. * * Used by routers that store positional parameter data. * * @example * ```ts * const map: ParamIndexMap = { userId: 0, postId: 1 }; * ``` */ type ParamIndexMap = Record<string, number>; /** * Represents a list of positional parameter values. * * Example: for `/user/123/post/456`, `stash` could be `['123', '456']`. */ type ParamStash = string[]; /** * Represents a key-value object mapping parameter names to string values. * * Example: `{ id: '123', action: 'edit' }` */ type Params = Record<string, string>; /** * The result of attempting to match a route. * * Can take one of two shapes: * * 1. **Indexed Parameters** * ```ts * [ * [ * [handlerA, { id: 0 }], * [handlerB, { id: 0, action: 1 }], * ], * ['123', 'edit'] * ] * ``` * * 2. **Resolved Parameters** * ```ts * [ * [ * [handlerA, { id: '123' }], * [handlerB, { id: '123', action: 'edit' }], * ] * ] * ``` */ type Result<T> = [[T, ParamIndexMap][], ParamStash] | [[T, Params][]]; //#endregion export { ClientErrorStatusCode, Handler, HttpStatusCode, RedirectStatusCode, Router$1 as Router, RouterRoute, ServerErrorStatusCode };