Add ability to specify middleware in AsyncRouter

This commit is contained in:
Jerko Steiner 2019-04-06 21:32:20 +08:00
parent 364972c97f
commit bbf18ed27a
3 changed files with 83 additions and 18 deletions

View File

@ -27,6 +27,11 @@ describe('AsyncRouter', () => {
patch: IHandler
head: {},
}
'/middleware': {
get: {
response: IResponse
}
}
}
const app = express()
@ -55,6 +60,16 @@ describe('AsyncRouter', () => {
asyncRouter.head('/test/:param', async req => {
return ''
})
asyncRouter.get('/middleware', [(req, res, next) => {
(req as any).testParam = 'middle'
next()
}, (req, res, next) => {
(req as any).testParam += 'ware'
next()
}], async req => {
const value = (req as any).testParam as string
return {value}
})
it('creates its own router when not provided', () => {
const r = new AsyncRouter<IMyApi>()
@ -69,5 +84,7 @@ describe('AsyncRouter', () => {
await request(app).options('/test/a').expect(200).expect('{"value":"a"}')
await request(app).patch('/test/a').expect(500)
await request(app).head('/test/a').expect(200)
await request(app).get('/middleware').expect(200)
.expect('{"value":"middleware"}')
})
})

View File

@ -1,6 +1,6 @@
import express from 'express'
import {IRoutes, TMethod} from '@rondo/common'
import {TTypedHandler} from './TTypedHandler'
import {TTypedHandler, TTypedMiddleware} from './TTypedHandler'
export class AsyncRouter<R extends IRoutes> {
readonly router: express.Router
@ -14,11 +14,21 @@ export class AsyncRouter<R extends IRoutes> {
protected addRoute<M extends TMethod, P extends keyof R & string>(
method: M,
path: P,
handler: TTypedHandler<R, P, M>,
...handlers: [TTypedHandler<R, P, M>] | [
Array<TTypedMiddleware<R, P, M>>,
TTypedHandler<R, P, M>,
]
) {
const addRoute = this.router[method].bind(this.router as any)
addRoute(path, this.wrapHandler(handler))
if (handlers.length === 2) {
const middleware = handlers[0]
const handler = handlers[1]
addRoute(path, ...middleware, this.wrapHandler(handler))
} else {
addRoute(path, this.wrapHandler(handlers[0]))
}
}
protected wrapHandler<M extends TMethod, P extends keyof R & string>(
@ -35,44 +45,72 @@ export class AsyncRouter<R extends IRoutes> {
get<P extends keyof R & string>(
path: P,
handler: TTypedHandler<R, P, 'get'>,
) {
this.addRoute('get', path, handler)
...handlers: [TTypedHandler<R, P, 'get'>] | [
Array<TTypedMiddleware<R, P, 'get'>>,
TTypedHandler<R, P, 'get'>,
]
): void {
this.addRoute('get', path, ...handlers)
}
post<P extends keyof R & string>(
path: P,
handler: TTypedHandler<R, P, 'post'>,
...handlers: [TTypedHandler<R, P, 'post'>] | [
Array<TTypedMiddleware<R, P, 'post'>>,
TTypedHandler<R, P, 'post'>,
]
) {
this.addRoute('post', path, handler)
this.addRoute('post', path, ...handlers)
}
put<P extends keyof R & string>(
path: P, handler: TTypedHandler<R, P, 'put'>,
path: P,
...handlers: [TTypedHandler<R, P, 'put'>] | [
Array<TTypedMiddleware<R, P, 'put'>>,
TTypedHandler<R, P, 'put'>,
]
) {
this.addRoute('put', path, handler)
this.addRoute('put', path, ...handlers)
}
delete<P extends keyof R & string>(
path: P, handler: TTypedHandler<R, P, 'delete'>) {
this.addRoute('delete', path, handler)
path: P,
...handlers: [TTypedHandler<R, P, 'delete'>] | [
Array<TTypedMiddleware<R, P, 'delete'>>,
TTypedHandler<R, P, 'delete'>,
]
) {
this.addRoute('delete', path, ...handlers)
}
head<P extends keyof R & string>(
path: P,
handler: TTypedHandler<R, P, 'head'>,
...handlers: [TTypedHandler<R, P, 'head'>] | [
Array<TTypedMiddleware<R, P, 'head'>>,
TTypedHandler<R, P, 'head'>,
]
) {
this.addRoute('head', path, handler)
this.addRoute('head', path, ...handlers)
}
options<P extends keyof R & string>(
path: P, handler: TTypedHandler<R, P, 'options'>) {
this.addRoute('options', path, handler)
path: P,
...handlers: [TTypedHandler<R, P, 'options'>] | [
Array<TTypedMiddleware<R, P, 'options'>>,
TTypedHandler<R, P, 'options'>,
]
) {
this.addRoute('options', path, ...handlers)
}
patch<P extends keyof R & string>(
path: P, handler: TTypedHandler<R, P, 'patch'>) {
this.addRoute('patch', path, handler)
path: P,
...handlers: [TTypedHandler<R, P, 'patch'>] | [
Array<TTypedMiddleware<R, P, 'patch'>>,
TTypedHandler<R, P, 'patch'>,
]
) {
this.addRoute('patch', path, ...handlers)
}
}

View File

@ -2,6 +2,16 @@ import express from 'express'
import {IRoutes, TMethod} from '@rondo/common'
import {ITypedRequest} from './ITypedRequest'
export type TTypedMiddleware<
R extends IRoutes,
P extends keyof R,
M extends TMethod
> = (
req: ITypedRequest<R[P][M]>,
res: express.Response,
next: express.NextFunction,
) => void
export type TTypedHandler<
R extends IRoutes,
P extends keyof R,