11import { OpenApiContext } from '../framework/openapi.context' ;
22import { validationError } from './util' ;
3- import * as multer from 'multer' ;
3+ import { Request } from 'express' ;
4+ import { OpenApiRequest , OpenApiRequestHandler } from '../framework/types' ;
5+ const multer = require ( 'multer' ) ;
46
5- export function multipart ( openApiContext : OpenApiContext , multerOpts : { } = { } ) {
7+ export function multipart (
8+ OpenApiContext : OpenApiContext ,
9+ multerOpts : { } = { } ,
10+ ) : OpenApiRequestHandler {
611 const mult = multer ( multerOpts ) ;
712 return ( req , res , next ) => {
813 if ( isMultipart ( req ) && isValidContentType ( req ) ) {
@@ -13,20 +18,22 @@ export function multipart(openApiContext: OpenApiContext, multerOpts: {} = {}) {
1318 // TODO:
1419 // If a form parameter 'file' is defined to take file value, but the user provides a string value instead
1520 // req.files will be empty and req.body.file will be populated with a string
16- // This will incorrectly PASS validation.
21+ // This will incorrectly PASS validation.
1722 // Instead, we should return a 400 with an invalid type e.g. file expects a file, but found string.
18- //
19- // In order to support this, we likely need to inspect the schema directly to find the type.
23+ //
24+ // In order to support this, we likely need to inspect the schema directly to find the type.
2025 // For example, if param with type: 'string', format: 'binary' is defined, we expect to see it in
2126 // req.files. If it's not present we should throw a 400
22- //
27+ //
2328 // This is a bit complex because the schema may be defined inline (easy) or via a $ref (complex) in which
2429 // case we must follow the $ref to check the type.
2530 if ( req . files ) {
2631 // add files to body
27- req . files . forEach ( f => {
28- req . body [ f . fieldname ] = '' ;
29- } ) ;
32+ ( < Express . Multer . File [ ] > req . files ) . forEach (
33+ ( f : Express . Multer . File ) => {
34+ req . body [ f . fieldname ] = '' ;
35+ } ,
36+ ) ;
3037 }
3138 next ( ) ;
3239 }
@@ -37,12 +44,12 @@ export function multipart(openApiContext: OpenApiContext, multerOpts: {} = {}) {
3744 } ;
3845}
3946
40- function isValidContentType ( req ) {
47+ function isValidContentType ( req : Request ) : boolean {
4148 const contentType = req . headers [ 'content-type' ] ;
4249 return ! contentType || contentType . includes ( 'multipart/form-data' ) ;
4350}
4451
45- function isMultipart ( req ) {
52+ function isMultipart ( req : OpenApiRequest ) : boolean {
4653 return (
4754 req . openapi &&
4855 req . openapi . schema &&
@@ -52,10 +59,9 @@ function isMultipart(req) {
5259 ) ;
5360}
5461
55- function error ( req , err ) {
62+ function error ( req : OpenApiRequest , err : Error ) {
5663 if ( err instanceof multer . MulterError ) {
5764 // TODO is special handling for MulterErrors needed
58- console . error ( err ) ;
5965 return validationError ( 500 , req . path , err . message ) ;
6066 } else {
6167 // HACK
@@ -66,7 +72,6 @@ function error(req, err) {
6672 if ( missingField ) {
6773 return validationError ( 400 , req . path , 'multipart file(s) required' ) ;
6874 } else {
69- console . error ( err ) ;
7075 return validationError ( 500 , req . path , err . message ) ;
7176 }
7277 }
0 commit comments