1
1
/* eslint-disable @typescript-eslint/naming-convention */
2
2
/* eslint-disable no-invalid-this */
3
3
import Ajv , { ErrorObject , ValidateFunction } from 'ajv'
4
- import OpenapiRequestCoercer from './ request-coercer'
5
- import { dummyLogger } from 'ts-log' ;
4
+ import OpenapiRequestCoercer from 'openapi- request-coercer'
5
+ import { dummyLogger } from 'ts-log'
6
6
import { OpenAPIV3 } from 'openapi-types'
7
7
import {
8
8
convertDatesToISOString ,
@@ -15,7 +15,7 @@ import {
15
15
hasComponentSchemas ,
16
16
isValidReferenceObject ,
17
17
Primitive ,
18
- isURLSearchParams
18
+ isURLSearchParams ,
19
19
} from './openapi-validator'
20
20
import { merge , openApiMergeRules } from 'allof-merge'
21
21
@@ -88,7 +88,7 @@ export class AjvOpenApiValidator {
88
88
constructor (
89
89
spec : OpenAPIV3 . Document ,
90
90
private ajv : Ajv ,
91
- validatorOpts ?: ValidatorOpts ,
91
+ validatorOpts ?: ValidatorOpts
92
92
) {
93
93
this . validatorOpts = validatorOpts ? { ...DEFAULT_VALIDATOR_OPTS , ...validatorOpts } : DEFAULT_VALIDATOR_OPTS
94
94
if ( this . validatorOpts . logger == undefined ) {
@@ -98,16 +98,25 @@ export class AjvOpenApiValidator {
98
98
this . initialize ( spec , this . validatorOpts . coerceTypes )
99
99
}
100
100
101
-
102
- validateQueryParams ( path : string , method : string , origParams : Record < string , Primitive > | URLSearchParams , strict = true ) : ErrorObj [ ] | undefined {
101
+ validateQueryParams (
102
+ path : string ,
103
+ method : string ,
104
+ origParams : Record < string , Primitive > | URLSearchParams ,
105
+ strict = true
106
+ ) : ErrorObj [ ] | undefined {
103
107
const parameterDefinitions = this . paramsValidators . filter ( ( p ) => p . path === path ?. toLowerCase ( ) && p . method === method ?. toLowerCase ( ) )
104
108
105
109
let errResponse : ErrorObj [ ] = [ ]
106
110
107
- let params = isURLSearchParams ( origParams ) ? Array . from ( origParams . entries ( ) ) . reduce ( ( acc , [ key , value ] ) => {
108
- acc [ key ] = value
109
- return acc
110
- } , { } as Record < string , Primitive > ) : origParams
111
+ let params = isURLSearchParams ( origParams )
112
+ ? Array . from ( origParams . entries ( ) ) . reduce (
113
+ ( acc , [ key , value ] ) => {
114
+ acc [ key ] = value
115
+ return acc
116
+ } ,
117
+ { } as Record < string , Primitive >
118
+ )
119
+ : origParams
111
120
112
121
if ( this . requestCoercer ) {
113
122
params = this . unserializeParameters ( params )
@@ -235,8 +244,6 @@ export class AjvOpenApiValidator {
235
244
return undefined
236
245
}
237
246
238
-
239
-
240
247
private initialize ( origSpec : OpenAPIV3 . Document , coerceTypes : boolean ) : void {
241
248
const schemaCompileFailures : string [ ] = [ ]
242
249
const spec : OpenAPIV3 . Document = merge ( origSpec , { rules : openApiMergeRules ( ) } )
@@ -364,7 +371,9 @@ export class AjvOpenApiValidator {
364
371
365
372
if ( schema ) {
366
373
const schemaName = `#/paths${ path . replace ( / [ { } ] / g, '' ) } /${ method } /response/${ key } `
367
- this . validatorOpts . logger . info ( `Adding response body validator '${ path } ', '${ method } ', '${ key } ' with schema '${ schemaName } '` )
374
+ this . validatorOpts . logger . info (
375
+ `Adding response body validator '${ path } ', '${ method } ', '${ key } ' with schema '${ schemaName } '`
376
+ )
368
377
this . ajv . addSchema ( schema , schemaName )
369
378
const validator = this . ajv . compile ( { $ref : schemaName } )
370
379
this . responseBodyValidators . push ( {
@@ -427,8 +436,8 @@ export class AjvOpenApiValidator {
427
436
} ,
428
437
validator,
429
438
} )
430
-
431
- if ( isValidReferenceObject ( resolvedParam . schema ) ) {
439
+
440
+ if ( coerceTypes && isValidReferenceObject ( resolvedParam . schema ) ) {
432
441
const fullyResolved = this . fullyResolveParameter ( spec , resolvedParam )
433
442
if ( fullyResolved ) {
434
443
resolvedParams . push ( fullyResolved )
@@ -438,13 +447,12 @@ export class AjvOpenApiValidator {
438
447
}
439
448
}
440
449
} )
441
-
450
+
442
451
if ( this . validatorOpts . coerceTypes == true && resolvedParams . length > 0 ) {
443
452
this . requestCoercer = new OpenapiRequestCoercer ( {
444
453
logger : this . validatorOpts . logger ,
445
454
enableObjectCoercion : true ,
446
455
parameters : resolvedParams ,
447
-
448
456
} )
449
457
}
450
458
}
@@ -470,18 +478,21 @@ export class AjvOpenApiValidator {
470
478
}
471
479
}
472
480
473
-
474
-
475
- private resolveRef ( document : OpenAPIV3 . Document , ref : string ) : any {
476
- const pathParts = ref . split ( '/' ) ;
477
-
478
- return pathParts . reduce ( ( current : any , part ) => {
479
- if ( part === '#' || part === '' ) return current ;
480
- return current ? current [ part ] : undefined ;
481
- } , document ) ;
482
- }
483
-
484
- private fullyResolveSchemaRefs ( document : OpenAPIV3 . Document , schema : OpenAPIV3 . SchemaObject | OpenAPIV3 . ReferenceObject , visited : Map < string , OpenAPIV3 . SchemaObject > = new Map < string , OpenAPIV3 . SchemaObject > ( ) ) : OpenAPIV3 . SchemaObject | undefined {
481
+ private resolveRef ( document : OpenAPIV3 . Document , ref : string ) : OpenAPIV3 . SchemaObject {
482
+ const pathParts = ref . split ( '/' )
483
+
484
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
485
+ return pathParts . reduce ( ( current : any , part ) => {
486
+ if ( part === '#' || part === '' ) return current
487
+ return current ? current [ part ] : undefined
488
+ } , document )
489
+ }
490
+
491
+ private fullyResolveSchemaRefs (
492
+ document : OpenAPIV3 . Document ,
493
+ schema : OpenAPIV3 . SchemaObject | OpenAPIV3 . ReferenceObject ,
494
+ visited : Map < string , OpenAPIV3 . SchemaObject > = new Map < string , OpenAPIV3 . SchemaObject > ( )
495
+ ) : OpenAPIV3 . SchemaObject | undefined {
485
496
if ( typeof schema !== 'object' ) {
486
497
return undefined
487
498
}
@@ -492,53 +503,58 @@ export class AjvOpenApiValidator {
492
503
return resolved
493
504
}
494
505
}
495
-
506
+
496
507
let resolvedSchema
497
- if ( isValidReferenceObject ( schema ) ) {
498
- resolvedSchema = this . resolveRef ( document , schema . $ref ) as OpenAPIV3 . SchemaObject ;
499
- visited . set ( schema . $ref , resolvedSchema ) ;
508
+ if ( isValidReferenceObject ( schema ) ) {
509
+ resolvedSchema = this . resolveRef ( document , schema . $ref ) as OpenAPIV3 . SchemaObject
510
+ visited . set ( schema . $ref , resolvedSchema )
500
511
} else {
501
512
resolvedSchema = schema
502
513
}
503
-
504
- for ( const key in resolvedSchema ) {
514
+
515
+ for ( const key in resolvedSchema ) {
505
516
if ( typeof resolvedSchema [ key as keyof OpenAPIV3 . SchemaObject ] === 'object' ) {
506
- resolvedSchema [ key as keyof OpenAPIV3 . SchemaObject ] = this . fullyResolveSchemaRefs ( document , resolvedSchema [ key as keyof OpenAPIV3 . SchemaObject ] , visited ) ;
507
- }
517
+ resolvedSchema [ key as keyof OpenAPIV3 . SchemaObject ] = this . fullyResolveSchemaRefs (
518
+ document ,
519
+ resolvedSchema [ key as keyof OpenAPIV3 . SchemaObject ] ,
520
+ visited
521
+ )
522
+ }
508
523
}
509
-
510
- return resolvedSchema ;
524
+
525
+ return resolvedSchema
511
526
}
512
-
513
- private fullyResolveParameter ( document : OpenAPIV3 . Document , parameter : OpenAPIV3 . ParameterObject ) : OpenAPIV3 . ParameterObject | undefined {
514
- if ( ! parameter . schema || typeof parameter . schema !== 'object' || ! isValidReferenceObject ( parameter . schema ) ) {
515
- return parameter ;
516
- }
517
-
518
- return { ...parameter , schema : this . fullyResolveSchemaRefs ( document , parameter . schema ) } ;
519
- }
520
-
521
- private unserializeParameters ( parameters : Record < string , Primitive > ) : Record < string , any > {
522
- const result : Record < string , any > = { } ;
527
+
528
+ private fullyResolveParameter ( document : OpenAPIV3 . Document , parameter : OpenAPIV3 . ParameterObject ) : OpenAPIV3 . ParameterObject | undefined {
529
+ if ( ! parameter . schema || typeof parameter . schema !== 'object' || ! isValidReferenceObject ( parameter . schema ) ) {
530
+ return parameter
531
+ }
532
+
533
+ return { ...parameter , schema : this . fullyResolveSchemaRefs ( document , parameter . schema ) }
534
+ }
535
+
536
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
537
+ private unserializeParameters ( parameters : Record < string , Primitive > ) : Record < string , any > {
538
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
539
+ const result : Record < string , any > = { }
523
540
for ( const key in parameters ) {
524
- const value = parameters [ key ] ;
525
- let target = result ;
526
- const splitKey = key . split ( '[' ) ;
527
- const lastKeyIndex = splitKey . length - 1 ;
528
-
529
- splitKey . forEach ( ( part , index ) => {
530
- const cleanPart = part . replace ( ']' , '' ) ;
531
-
532
- if ( index === lastKeyIndex ) {
533
- target [ cleanPart ] = typeof value === 'string' ? decodeURIComponent ( value ) : value // TODO is the decode necesary?
534
- } else {
535
- if ( ! target [ cleanPart ] ) target [ cleanPart ] = { } ;
536
- target = target [ cleanPart ] ;
537
- }
538
- } ) ;
541
+ const value = parameters [ key ]
542
+ let target = result
543
+ const splitKey = key . split ( '[' )
544
+ const lastKeyIndex = splitKey . length - 1
545
+
546
+ splitKey . forEach ( ( part , index ) => {
547
+ const cleanPart = part . replace ( ']' , '' )
548
+
549
+ if ( index === lastKeyIndex ) {
550
+ target [ cleanPart ] = value
551
+ } else {
552
+ if ( ! target [ cleanPart ] ) target [ cleanPart ] = { }
553
+ target = target [ cleanPart ]
554
+ }
555
+ } )
539
556
}
540
-
541
- return result ;
557
+
558
+ return result
542
559
}
543
-
544
- }
560
+ }
0 commit comments