You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
2.3 KiB

import Module from '../Module.ts'
import {Injectable} from '../../../../../di/src/decorator/Injection.ts'
import Kernel from '../Kernel.ts'
import {Logging} from '../../../service/logging/Logging.ts'
import {Request} from '../../Request.ts'
import ResponseFactory from '../../response/ResponseFactory.ts'
import {http, error} from '../../response/helpers.ts'
import {HTTPStatus} from '../../../const/http.ts'
@Injectable()
export default class ApplyRouteHandlers extends Module {
public static register(kernel: Kernel) {
kernel.register(this).core()
}
constructor(
protected readonly logger: Logging,
) {
super()
}
public async apply(request: Request): Promise<Request> {
if ( !request.route ) { // Route not found
const factory = http(HTTPStatus.NOT_FOUND)
return await factory.write(request)
}
if ( !Array.isArray(request.route.handlers) ) { // Route found but invalid HTTP method
const factory = http(HTTPStatus.METHOD_NOT_ALLOWED)
return await factory.write(request)
}
if ( request.route.handlers.length < 1 ) { // Route and method found, but no handlers
const factory = http(HTTPStatus.NOT_IMPLEMENTED)
return await factory.write(request)
}
let current_request: Request = request
for ( const handler of request.route.handlers ) {
try {
const result = await handler(current_request)
if ( result instanceof Request ) {
// If we got a request instance back, use that for further handlers
current_request = result
} else if ( result instanceof ResponseFactory ) {
// If we got a response factory back, write the response and move along
return await result.write(current_request)
}
} catch (e) {
this.logger.error('Error encountered while applying request handlers!')
this.logger.error(e)
// TODO determine response type (html | json, &c.)
const factory = error(e)
return await factory.write(request)
}
}
return current_request
}
}