@@ -62,6 +62,11 @@ export type Handler<
62
62
D extends Document = Document ,
63
63
> = ( context : Context < RequestBody , Params , Query , Headers , Cookies , D > , ...args : any [ ] ) => any | Promise < any > ;
64
64
65
+ /**
66
+ * Map of operation handlers
67
+ */
68
+ export type HandlerMap = { [ operationId : string ] : Handler | undefined } ;
69
+
65
70
export type BoolPredicate = ( context : Context , ...args : any [ ] ) => boolean ;
66
71
67
72
/**
@@ -90,15 +95,13 @@ export interface Options<D extends Document = Document> {
90
95
validate ?: boolean | BoolPredicate ;
91
96
ajvOpts ?: AjvOpts ;
92
97
customizeAjv ?: AjvCustomizer ;
93
- handlers ?: {
98
+ handlers ?: HandlerMap & {
94
99
notFound ?: Handler ;
95
100
notImplemented ?: Handler ;
96
101
validationFail ?: Handler ;
97
- [ handler : string ] : Handler | undefined ;
98
- } ;
99
- securityHandlers ?: {
100
- [ handler : string ] : Handler | undefined ;
101
102
} ;
103
+ securityHandlers ?: HandlerMap ;
104
+ ignoreTrailingSlashes ?: boolean ;
102
105
}
103
106
104
107
/**
@@ -123,7 +126,7 @@ export class OpenAPIBackend<D extends Document = Document> {
123
126
public ajvOpts : AjvOpts ;
124
127
public customizeAjv : AjvCustomizer | undefined ;
125
128
126
- public handlers : { [ operationId : string ] : Handler } ;
129
+ public handlers : HandlerMap ;
127
130
public allowedHandlers = [
128
131
'404' ,
129
132
'notFound' ,
@@ -137,7 +140,7 @@ export class OpenAPIBackend<D extends Document = Document> {
137
140
'postResponseHandler' ,
138
141
] ;
139
142
140
- public securityHandlers : { [ name : string ] : Handler } ;
143
+ public securityHandlers : HandlerMap ;
141
144
142
145
public router : OpenAPIRouter < D > ;
143
146
public validator : OpenAPIValidator < D > ;
@@ -157,26 +160,25 @@ export class OpenAPIBackend<D extends Document = Document> {
157
160
* @memberof OpenAPIBackend
158
161
*/
159
162
constructor ( opts : Options < D > ) {
160
- const optsWithDefaults = {
163
+ const optsWithDefaults : Options < D > = {
161
164
apiRoot : '/' ,
162
165
validate : true ,
163
166
strict : false ,
164
167
quick : false ,
165
168
ignoreTrailingSlashes : true ,
166
- ajvOpts : { } ,
167
- handlers : { } ,
168
- securityHandlers : { } ,
169
+ handlers : { } as HandlerMap ,
170
+ securityHandlers : { } as HandlerMap ,
169
171
...opts ,
170
172
} ;
171
- this . apiRoot = optsWithDefaults . apiRoot ;
173
+ this . apiRoot = optsWithDefaults . apiRoot ?? '/' ;
172
174
this . inputDocument = optsWithDefaults . definition ;
173
- this . strict = optsWithDefaults . strict ;
174
- this . quick = optsWithDefaults . quick ;
175
- this . validate = optsWithDefaults . validate ;
176
- this . ignoreTrailingSlashes = optsWithDefaults . ignoreTrailingSlashes ;
177
- this . handlers = { ...optsWithDefaults . handlers } ; // Copy to avoid mutating passed object
175
+ this . strict = ! ! optsWithDefaults . strict ;
176
+ this . quick = ! ! optsWithDefaults . quick ;
177
+ this . validate = ! ! optsWithDefaults . validate ;
178
+ this . ignoreTrailingSlashes = ! ! optsWithDefaults . ignoreTrailingSlashes ;
179
+ this . handlers = { ...optsWithDefaults . handlers } ; // Copy to avoid mutating passed object
178
180
this . securityHandlers = { ...optsWithDefaults . securityHandlers } ; // Copy to avoid mutating passed object
179
- this . ajvOpts = optsWithDefaults . ajvOpts ;
181
+ this . ajvOpts = optsWithDefaults . ajvOpts ?? { } ;
180
182
this . customizeAjv = optsWithDefaults . customizeAjv ;
181
183
}
182
184
@@ -257,7 +259,9 @@ export class OpenAPIBackend<D extends Document = Document> {
257
259
// register all security handlers
258
260
if ( this . securityHandlers ) {
259
261
for ( const [ name , handler ] of Object . entries ( this . securityHandlers ) ) {
260
- this . registerSecurityHandler ( name , handler ) ;
262
+ if ( handler ) {
263
+ this . registerSecurityHandler ( name , handler ) ;
264
+ }
261
265
}
262
266
}
263
267
@@ -331,9 +335,10 @@ export class OpenAPIBackend<D extends Document = Document> {
331
335
securitySchemes . map ( async ( name ) => {
332
336
securityHandlerResults [ name ] = undefined ;
333
337
if ( this . securityHandlers [ name ] ) {
338
+ const securityHandler = this . securityHandlers [ name ] ;
334
339
// return a promise that will set the security handler result
335
340
return await Promise . resolve ( )
336
- . then ( ( ) => this . securityHandlers [ name ] ( context as Context < D > , ...handlerArgs ) )
341
+ . then ( ( ) => securityHandler ( context as Context < D > , ...handlerArgs ) )
337
342
. then ( ( result : unknown ) => {
338
343
securityHandlerResults [ name ] = result ;
339
344
} )
@@ -389,7 +394,7 @@ export class OpenAPIBackend<D extends Document = Document> {
389
394
390
395
// call unauthorizedHandler handler if auth fails
391
396
if ( ! authorized && securityRequirements . length > 0 ) {
392
- const unauthorizedHandler : Handler = this . handlers [ 'unauthorizedHandler' ] ;
397
+ const unauthorizedHandler = this . handlers [ 'unauthorizedHandler' ] ;
393
398
if ( unauthorizedHandler ) {
394
399
return unauthorizedHandler ( context as Context < D > , ...handlerArgs ) ;
395
400
}
@@ -402,7 +407,7 @@ export class OpenAPIBackend<D extends Document = Document> {
402
407
: Boolean ( this . validate ) ;
403
408
404
409
// validate request
405
- const validationFailHandler : Handler = this . handlers [ 'validationFail' ] ;
410
+ const validationFailHandler = this . handlers [ 'validationFail' ] ;
406
411
if ( validate ) {
407
412
context . validation = this . validator . validateRequest ( req , context . operation ) ;
408
413
if ( context . validation . errors ) {
@@ -415,7 +420,7 @@ export class OpenAPIBackend<D extends Document = Document> {
415
420
}
416
421
417
422
// get operation handler
418
- const routeHandler : Handler = this . handlers [ operationId ] ;
423
+ const routeHandler = this . handlers [ operationId ] ;
419
424
if ( ! routeHandler ) {
420
425
// 501 not implemented
421
426
const notImplementedHandler = this . handlers [ '501' ] || this . handlers [ 'notImplemented' ] ;
@@ -430,7 +435,7 @@ export class OpenAPIBackend<D extends Document = Document> {
430
435
} ) . bind ( this ) ( ) ;
431
436
432
437
// post response handler
433
- const postResponseHandler : Handler = this . handlers [ 'postResponseHandler' ] ;
438
+ const postResponseHandler = this . handlers [ 'postResponseHandler' ] ;
434
439
if ( postResponseHandler ) {
435
440
// pass response to postResponseHandler
436
441
context . response = response ;
@@ -478,7 +483,7 @@ export class OpenAPIBackend<D extends Document = Document> {
478
483
* @param {{ [operationId: string]: Handler } } handlers
479
484
* @memberof OpenAPIBackend
480
485
*/
481
- public register ( handlers : { [ operationId : string ] : Handler } ) : void ;
486
+ public register < Handlers extends HandlerMap = HandlerMap > ( handlers : Handlers ) : void ;
482
487
483
488
/**
484
489
* Registers a handler for an operation
0 commit comments