diff --git a/src/middlewares/openapi.request.validator.ts b/src/middlewares/openapi.request.validator.ts index ee2fd094..de56edba 100644 --- a/src/middlewares/openapi.request.validator.ts +++ b/src/middlewares/openapi.request.validator.ts @@ -164,6 +164,11 @@ export class RequestValidator { body: req.body, }; const schemaBody = validator?.schemaBody; + + if (contentType.mediaType === 'multipart/form-data') { + this.multipartNested(req, schemaBody); + } + const discriminator = schemaBody?.properties?.body?._discriminator; const discriminatorValidator = this.discriminatorValidator( req, @@ -196,6 +201,21 @@ export class RequestValidator { }; } + private multipartNested(req, schemaBody) { + Object.keys(req.body).forEach((key) => { + const value = req.body[key]; + const type = schemaBody?.properties?.body?.properties[key]?.type; + if (['array', 'object'].includes(type)) { + try { + req.body[key] = JSON.parse(value); + } catch (e) { + // NOOP + } + } + }) + return null; + } + private discriminatorValidator(req, discriminator) { if (discriminator) { const { options, property, validators } = discriminator; diff --git a/test/common/test.yaml b/test/common/test.yaml index 46bc66d4..4d952dd9 100644 --- a/test/common/test.yaml +++ b/test/common/test.yaml @@ -160,6 +160,13 @@ paths: description: The photo type: string format: binary + array_with_objects: + type: array + items: + type: object + properties: + foo: + type: string required: true responses: 201: diff --git a/test/multipart.spec.ts b/test/multipart.spec.ts index ef2c5751..6b549524 100644 --- a/test/multipart.spec.ts +++ b/test/multipart.spec.ts @@ -127,11 +127,18 @@ describe('a multipart request', () => { }); it('should validate multipart file and metadata', async () => { + const array_with_objects = JSON.stringify([ + { + foo: 'bar' + } + ]); + await request(app) .post(`${app.basePath}/sample_2`) .set('Content-Type', 'multipart/form-data') .set('Accept', 'application/json') .attach('file', 'package.json') + .field('array_with_objects', array_with_objects) .field('metadata', 'some-metadata') .expect(200) .then((r) => {