UNPKG

@akala/core

Version:
114 lines (102 loc) 4.02 kB
import { process, convertToErrorMiddleware, isStandardMiddleware, isErrorMiddleware } from './shared.js'; import type { AnySyncMiddleware, ErrorMiddleware, Middleware, MiddlewareResult, OptionsResponse, SpecialNextParam } from './shared.js'; /** * MiddlewareIndexed class that implements Middleware. * @template T * @template TMiddleware * @template TSpecialNextParam */ export class MiddlewareIndexed<T extends unknown[], TMiddleware extends AnySyncMiddleware<T, TSpecialNextParam>, TSpecialNextParam extends string | undefined = SpecialNextParam> implements Middleware<T, TSpecialNextParam> { public readonly name?: string protected _delegate: Middleware<T, TSpecialNextParam>; /** * Constructor for MiddlewareIndexed. * @param {function} getIndexKey - Function to get the index key. * @param {string} [name] - Optional name for the middleware. */ constructor(private getIndexKey: (...args: T) => string, name?: string) { this.name = name; } /** * Get the keys from the index. * @returns {string[]} Array of keys. */ protected getKeys(): string[] { return Object.keys(this.index).filter(v => v !== ''); } protected readonly index: Record<string, TMiddleware> & { ''?: ErrorMiddleware<T, TSpecialNextParam> } = {}; /** * Use middleware for a specific key. * @param {string|null} key - The key for the middleware. * @param {AnySyncMiddleware} middleware - The middleware to use. * @returns {this} The current instance. */ public useMiddleware(key: null, middleware: Middleware<T, TSpecialNextParam>): this public useMiddleware(key: '', middleware: ErrorMiddleware<T, TSpecialNextParam>): this public useMiddleware(key: string, middleware: TMiddleware): this public useMiddleware(key: string, middleware: AnySyncMiddleware<T, TSpecialNextParam>): this { if (key === null) this._delegate = middleware as Middleware<T, TSpecialNextParam>; else this.index[key] = middleware as TMiddleware; return this; } /** * Use an error handler. * @param {function} handler - The error handler function. * @returns {this} The current instance. */ public useError(handler: ((error: Error | OptionsResponse, ...args: T) => unknown)): this { return this.useMiddleware('', convertToErrorMiddleware<T, TSpecialNextParam>(handler)); } /** * Process the request. * @template X * @param {...T} req - The request parameters. * @returns {X} The result of the process. */ public process<X = unknown>(...req: T): X { return process<X, T, TSpecialNextParam>(this, ...req); } /** * Handle an error. * @param {Error|OptionsResponse} error - The error to handle. * @param {...T} req - The request parameters. * @returns {MiddlewareResult<TSpecialNextParam>} The result of the error handling. */ public handleError(error: Error | OptionsResponse, ...req: T): MiddlewareResult<TSpecialNextParam> { if (isErrorMiddleware(this.index[''])) return this.index[''].handleError(error, ...req); return error; } /** * Handle the request. * @param {...T} req - The request parameters. * @returns {MiddlewareResult<TSpecialNextParam>} The result of the handling. */ public handle(...req: T): MiddlewareResult<TSpecialNextParam> { var key = this.getIndexKey(...req); if (!key || !this.index[key]) if (this._delegate) return this._delegate.handle(...req); else return; const middleware = this.index[key]; if (isStandardMiddleware(middleware)) { const e = middleware.handle(...req) if (typeof e === 'undefined' && this._delegate) return this._delegate.handle(...req) return e; } return; } }