lib/src/http/routing/Middleware.ts

58 lines
1.8 KiB
TypeScript

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<void>`, 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<T, THandlerArgs extends any[] = []> extends Middleware {
/** Look up the value. */
public abstract handle(...options: THandlerArgs): Awaitable<Either<ResponseObject, T>>
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<T> {
return left(what)
}
/** Alias for a good value return. */
right(what: T): Right<T> {
return right(what)
}
}