import {Request} from '../lifecycle/Request' import {ResponseObject} from './Route' import {Container} from '../../di' import {CanonicalItemClass} from '../../support/CanonicalReceiver' import {Awaitable, Either, ErrorWithContext, Left, left, Right, right} from '../../util' /** * Base class representing a middleware handler that can be applied to routes. */ export abstract class Middleware extends CanonicalItemClass { constructor( /** The request that will be handled by this middleware. */ protected readonly request: Request, ) { super() if ( !request ) { throw new Error('Middleware constructed without request') } } protected container(): Container { return this.request } /** * Apply the middleware to the request. * If this returns a response factory or similar item, that will be sent * as a response. * * If this returns `void | Promise`, the request will continue to the * next handler. */ public abstract apply(): ResponseObject } /** * A type of Middleware that produces a parameter that is passed to later handlers. * Can be used to do common look-ups, &c before routes. */ export abstract class ParameterMiddleware extends Middleware { /** Look up the value. */ public abstract handle(...options: THandlerArgs): Awaitable> apply(): ResponseObject { throw new ErrorWithContext('Attempted to apply parameter-providing middleware directly. Try using `parameterMiddleware()` instead.') } /** Alias for an error response return. */ left(what: T): Left { return left(what) } /** Alias for a good value return. */ right(what: T): Right { return right(what) } }