11'use strict' ;
22
33var SwaggerParser = require ( 'swagger-parser' ) ,
4- Ajv = require ( 'ajv' ) ,
5- Validators = require ( './utils/validators' ) ,
6- filesKeyword = require ( './customKeywords/files' ) ,
7- contentKeyword = require ( './customKeywords/contentTypeValidation' ) ,
84 InputValidationError = require ( './inputValidationError' ) ,
95 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' ) ,
1010 sourceResolver = require ( './utils/sourceResolver' ) ;
11-
1211var schemas = { } ;
1312var middlewareOptions ;
14- var ajvConfigBody ;
15- var ajvConfigParams ;
1613var framework ;
1714
1815/**
@@ -22,8 +19,6 @@ var framework;
2219 */
2320function init ( swaggerPath , options ) {
2421 middlewareOptions = options || { } ;
25- ajvConfigBody = middlewareOptions . ajvConfigBody || { } ;
26- ajvConfigParams = middlewareOptions . ajvConfigParams || { } ;
2722 framework = middlewareOptions . framework ? require ( `./frameworks/${ middlewareOptions . framework } ` ) : require ( './frameworks/express' ) ;
2823 const makeOptionalAttributesNullable = middlewareOptions . makeOptionalAttributesNullable || false ;
2924
@@ -39,19 +34,21 @@ function init(swaggerPath, options) {
3934 Object . keys ( dereferenced . paths [ currentPath ] ) . filter ( function ( parameter ) { return parameter !== 'parameters' } )
4035 . forEach ( function ( currentMethod ) {
4136 schemas [ parsedPath ] [ currentMethod . toLowerCase ( ) ] = { } ;
42-
37+ const isOpenApi3 = dereferenced . openapi === '3.0.0' ;
4338 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+ }
5552 }
5653
5754 let localParameters = parameters . filter ( function ( parameter ) {
@@ -60,7 +57,7 @@ function init(swaggerPath, options) {
6057
6158 if ( localParameters . length > 0 || middlewareOptions . contentTypeValidation ) {
6259 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 ) ;
6461 }
6562 } ) ;
6663 } ) ;
@@ -69,32 +66,6 @@ function init(swaggerPath, options) {
6966 return Promise . reject ( error ) ;
7067 } ) ;
7168}
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-
9869/**
9970 * The middleware - should be called for each express route
10071 * @param {any } req
@@ -141,55 +112,6 @@ function _validateParams(headers, pathParams, query, files, path, method) {
141112 } ) ;
142113}
143114
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-
193115function createContentTypeHeaders ( validate , contentTypes ) {
194116 if ( ! validate || ! contentTypes ) return ;
195117
@@ -198,16 +120,16 @@ function createContentTypeHeaders(validate, contentTypes) {
198120 } ;
199121}
200122
201- function buildParametersValidation ( parameters , contentTypes ) {
123+ function buildParametersValidation ( parameters , contentTypes , middlewareOptions ) {
202124 const defaultAjvOptions = {
203125 allErrors : true ,
204126 coerceTypes : 'array'
205127 // unknownFormats: 'ignore'
206128 } ;
207- const options = Object . assign ( { } , defaultAjvOptions , ajvConfigParams ) ;
129+ const options = Object . assign ( { } , defaultAjvOptions , middlewareOptions . ajvConfigParams ) ;
208130 let ajv = new Ajv ( options ) ;
209131
210- addCustomKeyword ( ajv , middlewareOptions . formats ) ;
132+ ajvUtils . addCustomKeyword ( ajv , middlewareOptions . formats ) ;
211133
212134 var ajvParametersSchema = {
213135 title : 'HTTP parameters' ,
0 commit comments