1
1
'use strict' ;
2
2
3
3
var SwaggerParser = require ( 'swagger-parser' ) ,
4
- Ajv = require ( 'ajv' ) ,
5
- Validators = require ( './utils/validators' ) ,
6
- filesKeyword = require ( './customKeywords/files' ) ,
7
- contentKeyword = require ( './customKeywords/contentTypeValidation' ) ,
8
4
InputValidationError = require ( './inputValidationError' ) ,
9
5
schemaPreprocessor = require ( './utils/schema-preprocessor' ) ,
6
+ swagger3 = require ( './swagger3/open-api3' ) ,
7
+ swagger2 = require ( './swagger2' ) ,
8
+ ajvUtils = require ( './utils/ajv-utils' ) ,
9
+ Ajv = require ( 'ajv' ) ,
10
10
sourceResolver = require ( './utils/sourceResolver' ) ;
11
-
12
11
var schemas = { } ;
13
12
var middlewareOptions ;
14
- var ajvConfigBody ;
15
- var ajvConfigParams ;
16
13
var framework ;
17
14
18
15
/**
@@ -22,8 +19,6 @@ var framework;
22
19
*/
23
20
function init ( swaggerPath , options ) {
24
21
middlewareOptions = options || { } ;
25
- ajvConfigBody = middlewareOptions . ajvConfigBody || { } ;
26
- ajvConfigParams = middlewareOptions . ajvConfigParams || { } ;
27
22
framework = middlewareOptions . framework ? require ( `./frameworks/${ middlewareOptions . framework } ` ) : require ( './frameworks/express' ) ;
28
23
const makeOptionalAttributesNullable = middlewareOptions . makeOptionalAttributesNullable || false ;
29
24
@@ -39,19 +34,21 @@ function init(swaggerPath, options) {
39
34
Object . keys ( dereferenced . paths [ currentPath ] ) . filter ( function ( parameter ) { return parameter !== 'parameters' } )
40
35
. forEach ( function ( currentMethod ) {
41
36
schemas [ parsedPath ] [ currentMethod . toLowerCase ( ) ] = { } ;
42
-
37
+ const isOpenApi3 = dereferenced . openapi === '3.0.0' ;
43
38
const parameters = dereferenced . paths [ currentPath ] [ currentMethod ] . parameters || [ ] ;
44
-
45
- let bodySchema = middlewareOptions . expectFormFieldsInBody
46
- ? parameters . filter ( function ( parameter ) { return ( parameter . in === 'body' || ( parameter . in === 'formData' && parameter . type !== 'file' ) ) } )
47
- : parameters . filter ( function ( parameter ) { return parameter . in === 'body' } ) ;
48
-
49
- if ( makeOptionalAttributesNullable ) {
50
- schemaPreprocessor . makeOptionalAttributesNullable ( bodySchema ) ;
51
- }
52
- if ( bodySchema . length > 0 ) {
53
- const validatedBodySchema = _getValidatedBodySchema ( bodySchema ) ;
54
- schemas [ parsedPath ] [ currentMethod ] . body = buildBodyValidation ( validatedBodySchema , dereferenced . definitions , swaggers [ 1 ] , currentPath , currentMethod , parsedPath ) ;
39
+ if ( isOpenApi3 ) {
40
+ schemas [ parsedPath ] [ currentMethod ] . body = swagger3 . buildBodyValidation ( dereferenced , swaggers [ 1 ] , currentPath , currentMethod , middlewareOptions ) ;
41
+ } else {
42
+ let bodySchema = middlewareOptions . expectFormFieldsInBody
43
+ ? parameters . filter ( function ( parameter ) { return ( parameter . in === 'body' || ( parameter . in === 'formData' && parameter . type !== 'file' ) ) } )
44
+ : parameters . filter ( function ( parameter ) { return parameter . in === 'body' } ) ;
45
+ if ( makeOptionalAttributesNullable ) {
46
+ schemaPreprocessor . makeOptionalAttributesNullable ( bodySchema ) ;
47
+ }
48
+ if ( bodySchema . length > 0 ) {
49
+ const validatedBodySchema = swagger2 . getValidatedBodySchema ( bodySchema ) ;
50
+ schemas [ parsedPath ] [ currentMethod ] . body = swagger2 . buildBodyValidation ( validatedBodySchema , dereferenced . definitions , swaggers [ 1 ] , currentPath , currentMethod , parsedPath , middlewareOptions ) ;
51
+ }
55
52
}
56
53
57
54
let localParameters = parameters . filter ( function ( parameter ) {
@@ -60,7 +57,7 @@ function init(swaggerPath, options) {
60
57
61
58
if ( localParameters . length > 0 || middlewareOptions . contentTypeValidation ) {
62
59
schemas [ parsedPath ] [ currentMethod ] . parameters = buildParametersValidation ( localParameters ,
63
- dereferenced . paths [ currentPath ] [ currentMethod ] . consumes || dereferenced . paths [ currentPath ] . consumes || dereferenced . consumes ) ;
60
+ dereferenced . paths [ currentPath ] [ currentMethod ] . consumes || dereferenced . paths [ currentPath ] . consumes || dereferenced . consumes , middlewareOptions ) ;
64
61
}
65
62
} ) ;
66
63
} ) ;
@@ -69,32 +66,6 @@ function init(swaggerPath, options) {
69
66
return Promise . reject ( error ) ;
70
67
} ) ;
71
68
}
72
-
73
- function _getValidatedBodySchema ( bodySchema ) {
74
- let validatedBodySchema ;
75
- if ( bodySchema [ 0 ] . in === 'body' ) {
76
- // if we are processing schema for a simple JSON payload, no additional processing needed
77
- validatedBodySchema = bodySchema [ 0 ] . schema ;
78
- } else if ( bodySchema [ 0 ] . in === 'formData' ) {
79
- // if we are processing multipart form, assemble body schema from form field schemas
80
- validatedBodySchema = {
81
- required : [ ] ,
82
- properties : { }
83
- } ;
84
- bodySchema . forEach ( ( formField ) => {
85
- if ( formField . type !== 'file' ) {
86
- validatedBodySchema . properties [ formField . name ] = {
87
- type : formField . type
88
- } ;
89
- if ( formField . required ) {
90
- validatedBodySchema . required . push ( formField . name ) ;
91
- }
92
- }
93
- } ) ;
94
- }
95
- return validatedBodySchema ;
96
- }
97
-
98
69
/**
99
70
* The middleware - should be called for each express route
100
71
* @param {any } req
@@ -141,55 +112,6 @@ function _validateParams(headers, pathParams, query, files, path, method) {
141
112
} ) ;
142
113
}
143
114
144
- function addCustomKeyword ( ajv , formats ) {
145
- if ( formats ) {
146
- formats . forEach ( function ( format ) {
147
- ajv . addFormat ( format . name , format . pattern ) ;
148
- } ) ;
149
- }
150
-
151
- ajv . addKeyword ( 'files' , filesKeyword ) ;
152
- ajv . addKeyword ( 'content' , contentKeyword ) ;
153
- }
154
-
155
- function buildBodyValidation ( schema , swaggerDefinitions , originalSwagger , currentPath , currentMethod , parsedPath ) {
156
- const defaultAjvOptions = {
157
- allErrors : true
158
- // unknownFormats: 'ignore'
159
- } ;
160
- const options = Object . assign ( { } , defaultAjvOptions , ajvConfigBody ) ;
161
- let ajv = new Ajv ( options ) ;
162
-
163
- addCustomKeyword ( ajv , middlewareOptions . formats ) ;
164
-
165
- if ( schema . discriminator ) {
166
- return buildInheritance ( schema . discriminator , swaggerDefinitions , originalSwagger , currentPath , currentMethod , parsedPath , ajv ) ;
167
- } else {
168
- return new Validators . SimpleValidator ( ajv . compile ( schema ) ) ;
169
- }
170
- }
171
-
172
- function buildInheritance ( discriminator , dereferencedDefinitions , swagger , currentPath , currentMethod , parsedPath , ajv ) {
173
- let bodySchema = swagger . paths [ currentPath ] [ currentMethod ] . parameters . filter ( function ( parameter ) { return parameter . in === 'body' } ) [ 0 ] ;
174
- var inheritsObject = {
175
- inheritance : [ ]
176
- } ;
177
- inheritsObject . discriminator = discriminator ;
178
-
179
- Object . keys ( swagger . definitions ) . forEach ( key => {
180
- if ( swagger . definitions [ key ] . allOf ) {
181
- swagger . definitions [ key ] . allOf . forEach ( element => {
182
- if ( element [ '$ref' ] && element [ '$ref' ] === bodySchema . schema [ '$ref' ] ) {
183
- inheritsObject [ key ] = ajv . compile ( dereferencedDefinitions [ key ] ) ;
184
- inheritsObject . inheritance . push ( key ) ;
185
- }
186
- } ) ;
187
- }
188
- } , this ) ;
189
-
190
- return new Validators . OneOfValidator ( inheritsObject ) ;
191
- }
192
-
193
115
function createContentTypeHeaders ( validate , contentTypes ) {
194
116
if ( ! validate || ! contentTypes ) return ;
195
117
@@ -198,16 +120,16 @@ function createContentTypeHeaders(validate, contentTypes) {
198
120
} ;
199
121
}
200
122
201
- function buildParametersValidation ( parameters , contentTypes ) {
123
+ function buildParametersValidation ( parameters , contentTypes , middlewareOptions ) {
202
124
const defaultAjvOptions = {
203
125
allErrors : true ,
204
126
coerceTypes : 'array'
205
127
// unknownFormats: 'ignore'
206
128
} ;
207
- const options = Object . assign ( { } , defaultAjvOptions , ajvConfigParams ) ;
129
+ const options = Object . assign ( { } , defaultAjvOptions , middlewareOptions . ajvConfigParams ) ;
208
130
let ajv = new Ajv ( options ) ;
209
131
210
- addCustomKeyword ( ajv , middlewareOptions . formats ) ;
132
+ ajvUtils . addCustomKeyword ( ajv , middlewareOptions . formats ) ;
211
133
212
134
var ajvParametersSchema = {
213
135
title : 'HTTP parameters' ,
0 commit comments